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?
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!
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" }]
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.
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.
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 .
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:
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"}]
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);