Opzoekwaarde in een lijst met lijsten, met behulp van js

Ik heb een lijst met gegevens in JavaScript die er als volgt uitziet:

[[152, 48, 'http://www.google.com'], 
 [198, 47, 'http://www.stackoverflow.com'], 
 [199, 45, 'http://www.apple.com']]

Ik gebruik flot om een ​​plot te maken en probeer deze derde waarde door te geven om toegang te krijgen tot een hyperlink vanaf het punt. Als zodanig probeer ik de derde waarde van elke lijst op te zoeken door de eerste twee te gebruiken als opzoektoetsen (bijv. [[x, y, hyperlink], [x2, y2, hyperlink2]] , klik op een punt en gebruik dan de juiste (x, y) om de bijbehorende hyperlink te vinden)

Is er hoe dan ook om dit te doen, of moet ik wat woordenboeken voor x en y doorgeven aan JavaScript en dan de algemene variabele vinden van de twee lijsten die zijn opgezocht? In python weet ik dat je een filter van de lijst op de x waarde met itemgetter kunt doen en dan een link opzoeken die overeenkomt met de waarde y . Maar ik weet bijna niets van JS, dus kan een oplossing voor het maken van ID's met (x, y) worden gegeven, of indien niet mogelijk of geadviseerd, dan is een oplossing voor het nemen van twee lijsten (van x en y vals) en een gemeenschappelijke waarde vinden (indien meerdere, alleen één, iemand)?

1

3 antwoord

U kunt gebruik maken van de array .filter() methode om erachter te komen of bepaalde elementen overeenkomen met de opgegeven x en y. (Merk op dat IE .filter() niet tot versie 9 ondersteunde, maar MDN heeft een schijf die u kunt opnemen).

var data = [[152, 48, 'http://www.google.com'],
            [198, 47, 'http://www.stackoverflow.com'],
            [199, 45, 'http://www.apple.com']];

function getURLForPoint1(x, y) {
    var p = data.filter(function(el) {
        return (el[0] === x && el[1] === y);
    });
    if (p.length === 1) return p[0][2];
   //else 0 or more than 1 elements mathced so return undefined
}

Als alternatief kunt u een woordenboekobject vooraan maken en dan toekomstige opzoekingen doen vanuit het woordenboek:

var getURLForPoint2 = function() {
    var dataDictionary = {}, i;
    for (i = 0; i < data.length; i++)
       dataDictionary[data[i][0]+" "+data[i][1]] = data[i][2];

    return function(x, y) {
       return dataDictionary[x + " " + y];
    };
}();

Hoe dan ook, ik heb het zo gecodeerd dat als je om een ​​punt vraagt ​​dat niet in de lijst staat, je undefined terug krijgt, maar je kunt dat natuurlijk veranderen om een ​​lege string terug te geven of een uitzondering of wat je maar wilt.

alert(getURLForPoint1(198, 47));   //'http://www.stackoverflow.com'
alert(getURLForPoint2(198, 47));   //'http://www.stackoverflow.com'
alert(getURLForPoint2(4, 5));      //undefined

Demo van beide: http://jsfiddle.net/WdSAz/

5
toegevoegd

Sorry, geen snelkoppeling om het in JS te doen behalve om gewoon door de lijst te bladeren en degene te vinden die de overeenkomende "x" en "y" waarde heeft.

Afhankelijk van hoe groot uw lijst is (en of deze lijst wel of niet wordt gebruikt voor iets anders ...), kunt u de gegevens herstructureren om deze efficiënter te maken. Doe bijvoorbeeld een structuur zoals (verondersteld mogelijk om bijvoorbeeld x1, y1 vs x1, y2 te hebben)

x1 > y1 > url
x1 > y2 > url
x2 > y1 > url
etc...

dan kun je onmiddellijk naar de 2e level "y" lijst springen door de "x" index, en de enige looping zou zijn hoeveel "y" waarden dezelfde "x" waarde delen

Bewerk:

eigenlijk als je nog een stap verder wilt gaan met het reorganiseren van de gegevens, zou je zoiets als dit kunnen doen:

<script type='text/javascript'>
var list = {
  1 : {
    1 : 'foobar 1,1',
    2 : 'foobar 1,2'
  },
  2 : {
    1 : 'foobar 2,1',
    2 : 'foobar 2,2'
  },
};

</script>

waarmee je dit bijvoorbeeld kunt doen

var x = 1;
var y = 2;
alert(list[x][y]);
2
toegevoegd
Merk op dat als u probeert punten op te halen waar de x -coördinaat zich niet in uw -lijst bevindt, dit een JS-fout oplevert omdat dan lijst [x] zou zijn niet gedefinieerd zijn en je kunt undefined [y] niet doen.
toegevoegd de auteur nnnnnn, de bron
Wat ik bedoel is dat de test voor het bestaan ​​een tweestapsproces zou zijn (en ik wees erop dat het een beetje lastig was): je zou moeten testen of lijst [x] is gedefinieerd voordat u kunt testen of lijst [x] [y] is gedefinieerd, anders krijgt u niet alleen undefined terug, maar krijgt u een JS-fout die de uitvoering van de code stopt. Maar ja, als het hele ding was ingepakt in een accessor-functie, dan zou de functie dat natuurlijk wel doen ...
toegevoegd de auteur nnnnnn, de bron
nou ja, het is een goede gewoonte om te controleren of het bestaat voordat je het gebruikt; dat is niet echt een direct onderdeel van deze oefening ... en er zijn veel manieren om te controleren of het bestaat.
toegevoegd de auteur Crayon Violent, de bron

iets als dit misschien

  var findX = 198
  var findY = 47
  var targetUrl
  for (var i=0; i
0
toegevoegd
Waarom heb je een geneste lus? Een enkele lus zal het doen - merk op dat uw j variabele geen array is, dus j [0] werkt niet. (Merk ook op dat u waarschijnlijk == (niet = ) in uw if had bedoeld.)
toegevoegd de auteur nnnnnn, de bron
voor ... in loops zijn bedoeld om objecteigenschappen te herhalen en kunnen gevaarlijk zijn om te gebruiken voor arrays. Gebruik altijd voor (var i = 0; i om reeksen te herhalen. Zie hier: JavaScript verbeterd voor in lus "> stackoverflow.com/questions/1885317/…
toegevoegd de auteur Trevor, de bron
wordt een gekartelde array genoemd denk ik. Het is een soort van multidimensionale array die je meestal in Java aantreft van wat ik me herinner.
toegevoegd de auteur Graham.Fraser, de bron