it-swarm.com.de

Wie finde ich einen Wert in einem mehrdimensionalen Objekt/Array in Javascript?

Ich habe ein mehrdimensionales Objekt (es ist im Grunde ein Array):

Object = {
   1 : { name : bob , dinner : pizza },
   2 : { name : john , dinner : sushi },
   3 : { name : larry, dinner : hummus }
}

Ich möchte in der Lage sein, das Objekt/Array danach zu durchsuchen, wo der Schlüssel "Abendessen" ist, und zu sehen, ob es mit "Sushi" übereinstimmt.

Ich weiß, dass jQuery $ .inArray hat, aber es scheint nicht bei mehrdimensionalen Arrays zu funktionieren. Oder vielleicht irre ich mich. indexOf scheint auch nur auf einer Arrayebene zu funktionieren.

Gibt es dafür keine Funktion oder keinen vorhandenen Code?

79
Questioner

Wenn Sie ein Array wie haben

var people = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

Sie können die Methode filter eines Array-Objekts verwenden:

people.filter(function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]

In neueren JavaScript-Implementierungen können Sie einen Funktionsausdruck verwenden:

people.filter(p => p.dinner == "sushi")
  // => [{ "name": "john", "dinner": "sushi" }]

Sie können nach Personen mit "dinner": "sushi" suchen, indem Sie eine map verwenden.

people.map(function (person) {
  if (person.dinner == "sushi") {
    return person
  } else {
    return null
  }
}); // => [null, { "name": "john", "dinner": "sushi" }, null]

oder eine reduce

people.reduce(function (sushiPeople, person) {
  if (person.dinner == "sushi") {
    return sushiPeople.concat(person);
  } else {
    return sushiPeople
  }
}, []); // => [{ "name": "john", "dinner": "sushi" }]

Ich bin sicher, Sie können dies auf beliebige Schlüssel und Werte verallgemeinern!

178
adamse

jQuery verfügt über eine integrierte Methode jQuery.grep , die ähnlich funktioniert wie die ES5-Funktion filter aus @ adamse's Answer und sollte mit älteren Browsern problemlos funktionieren.

Am Beispiel von adamse:

var peoples = [
  { "name": "bob", "dinner": "pizza" },
  { "name": "john", "dinner": "sushi" },
  { "name": "larry", "dinner": "hummus" }
];

sie können folgendes tun

jQuery.grep(peoples, function (person) { return person.dinner == "sushi" });
  // => [{ "name": "john", "dinner": "sushi" }]
17
Zach Lysobey

Wenn Sie diese Suche häufig durchführen, sollten Sie das Format Ihres Objekts ändern, sodass das Abendessen tatsächlich ein Schlüssel ist. Dies ist etwa so, als würden Sie in einer Datenbanktabelle einen primären gruppierten Schlüssel zuweisen. Also zum Beispiel: 

Obj = { 'pizza' : { 'name' : 'bob' }, 'sushi' : { 'name' : 'john' } }

Sie können jetzt einfach wie folgt darauf zugreifen: Object['sushi']['name']

Oder wenn das Objekt wirklich so einfach ist (nur "Name" im Objekt), können Sie es einfach wie folgt ändern:

Obj = { 'pizza' : 'bob', 'sushi' : 'john' }

Und dann auf es zugreifen: Object['sushi'].

Es ist natürlich nicht immer möglich oder zu Ihrem Vorteil, Ihr Datenobjekt so umzustrukturieren, aber der Punkt ist, manchmal ist die beste Antwort, zu prüfen, ob Ihr Datenobjekt am besten strukturiert ist. Das Erstellen eines Schlüssels wie diesem kann schneller und sauberer sein.

10
dallin
var getKeyByDinner = function(obj, dinner) {
    var returnKey = -1;

    $.each(obj, function(key, info) {
        if (info.dinner == dinner) {
           returnKey = key;
           return false; 
        };   
    });

    return returnKey;       

}

jsFiddle .

Solange -1 kein gültiger Schlüssel ist.

8
alex

Sie finden das Objekt in Array mit Alasql library:

var data = [ { name : "bob" , dinner : "pizza" }, { name : "john" , dinner : "sushi" },
     { name : "larry", dinner : "hummus" } ];

var res = alasql('SELECT * FROM ? WHERE dinner="sushi"',[data]);

Versuchen Sie dieses Beispiel in jsFiddle .

2
agershun

Sie können eine einfache for-Schleife verwenden:

for (prop in Obj){
    if (Obj[prop]['dinner'] === 'sushi'){

        // Do stuff with found object. E.g. put it into an array:
        arrFoo.Push(Obj[prop]);
    }
}

Im folgenden Geigenbeispiel werden alle Objekte, die dinner:sushi enthalten, in ein Array eingefügt:

https://jsfiddle.net/3asvkLn6/1/

1
Rotareti

Es gibt bereits viele gute Antworten. Warum also nicht noch eine, verwenden Sie eine Bibliothek wie lodash oder Unterstrich :)

obj = {
   1 : { name : 'bob' , dinner : 'pizza' },
   2 : { name : 'john' , dinner : 'sushi' },
   3 : { name : 'larry', dinner : 'hummus' }
}

_.where(obj, {dinner: 'pizza'})
>> [{"name":"bob","dinner":"pizza"}]
1
TomDotTom

Ich musste eine verschachtelte Sitemap-Struktur für das erste Blattelement suchen, das einen bestimmten Pfad bewirkt. Der folgende Code ist nur mit .map().filter() und .reduce entstanden. Gibt den letzten gefundenen Artikel zurück, der dem Pfad /c entspricht.

var sitemap = {
  nodes: [
    {
      items: [{ path: "/a" }, { path: "/b" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    },
    {
      items: [{ path: "/c" }, { path: "/d" }]
    }
  ]
};

const item = sitemap.nodes
  .map(n => n.items.filter(i => i.path === "/c"))
  .reduce((last, now) => last.concat(now))
  .reduce((last, now) => now);

 Edit 4n4904z07

0
Marc