Ähnlich wie bei brnwdrng suche ich nach einer Möglichkeit, ein JSON-ähnliches Objekt zu durchsuchen.
Angenommen, die Struktur meines Objekts ist wie folgt:
TestObj = {
"Categories": [{
"Products": [{
"id": "a01",
"name": "Pine",
"description": "Short description of pine."
},
{
"id": "a02",
"name": "Birch",
"description": "Short description of birch."
},
{
"id": "a03",
"name": "Poplar",
"description": "Short description of poplar."
}],
"id": "A",
"title": "Cheap",
"description": "Short description of category A."
},
{
"Product": [{
"id": "b01",
"name": "Maple",
"description": "Short description of maple."
},
{
"id": "b02",
"name": "Oak",
"description": "Short description of oak."
},
{
"id": "b03",
"name": "Bamboo",
"description": "Short description of bamboo."
}],
"id": "B",
"title": "Moderate",
"description": "Short description of category B."
}]
};
Ich möchte ein Objekt mit id = "A" erhalten.
Ich habe alle möglichen Dinge ausprobiert wie:
$(TestObj.find(":id='A'"))
aber nichts scheint zu funktionieren.
Kann sich jemand eine Möglichkeit vorstellen, einen Artikel anhand einiger Kriterien abzurufen, ohne "jeder" zu verwenden?
jquery
jquery-selectors
J. Ed
quelle
quelle
Antworten:
jQuery funktioniert nicht mit einfachen Objektliteralen. Sie können die folgende Funktion auf ähnliche Weise verwenden, um alle IDs (oder andere Eigenschaften) zu durchsuchen, unabhängig von ihrer Tiefe im Objekt:
function getObjects(obj, key, val) { var objects = []; for (var i in obj) { if (!obj.hasOwnProperty(i)) continue; if (typeof obj[i] == 'object') { objects = objects.concat(getObjects(obj[i], key, val)); } else if (i == key && obj[key] == val) { objects.push(obj); } } return objects; }
Verwenden Sie wie folgt:
getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects
quelle
for...in
for...in
aber wenn ein beliebiges Objekt angegeben wird, gibt es keine Garantie dafür, dass Arrays darin "echte" Arrays sind. Selbst wenn Sie den Konstruktor, bestimmte Methoden wie Slice usw. überprüfen, kann es dennoch expando-Eigenschaften geben, sodass ich keinen Sinn darin sehe, die Logik weiter zu definieren.Object.prototype.toString.call(obj)
die es geben würde[object Array]
.[]
), können Sie ihnen dennoch (nicht numerische) Eigenschaften hinzufügen, über die Sie möglicherweise iterieren möchten oder nicht. AnsonstenhasOwnProperty()
schützt die Überprüfung vor dem Iterieren von Eigenschaften des Prototyps.for...in
und Arrays konzentriert, von denen ich nicht wirklich wusste, was du machsthasOwnProperty()
... egal, ich nehme alles zurück;) und +1 als Erlösung: o)Die reine Javascript-Lösung ist besser, aber eine jQuery-Methode wäre die Verwendung der jQuery-Grep- und / oder Map- Methoden. Wahrscheinlich nicht viel besser als $ .each
jQuery.grep(TestObj, function(obj) { return obj.id === "A"; });
oder
jQuery.map(TestObj, function(obj) { if(obj.id === "A") return obj; // or return obj.name, whatever. });
Gibt ein Array der übereinstimmenden Objekte oder der nachgeschlagenen Werte im Fall einer Karte zurück. Könnte in der Lage sein, das zu tun, was Sie wollen, indem Sie diese einfach verwenden.
In diesem Beispiel müssten Sie jedoch eine Rekursion durchführen, da die Daten kein flaches Array sind und wir beliebige Strukturen, Schlüssel und Werte akzeptieren, genau wie bei den reinen Javascript-Lösungen.
function getObjects(obj, key, val) { var retv = []; if(jQuery.isPlainObject(obj)) { if(obj[key] === val) // may want to add obj.hasOwnProperty(key) here. retv.push(obj); var objects = jQuery.grep(obj, function(elem) { return (jQuery.isArray(elem) || jQuery.isPlainObject(elem)); }); retv.concat(jQuery.map(objects, function(elem){ return getObjects(elem, key, val); })); } return retv; }
Im Wesentlichen dieselbe wie die Antwort von Box9, jedoch mit den Funktionen des Dienstprogramms jQuery, wo dies nützlich ist.
········
quelle
jQuery.grep(TestObj, function(obj) { return obj.id === "A"; })[0].PropertyName;
$.grep()
daran, dass ein Array zurückgegeben wird. Das heißt, wenn Sie nach einem einzelnen Artikel suchen, müssen Sie ihn verwenden, um darauf zugreifen zu können$.grep(/* whatever */)[0]
Dies funktioniert bei mir unter [{"id": "data"}, {"id": "data"}]
function getObjects(obj, key, val) { var newObj = false; $.each(obj, function() { var testObject = this; $.each(testObject, function(k,v) { //alert(k); if(val == v && k == key) { newObj = testObject; } }); }); return newObj; }
quelle
Für eine Dimension json können Sie Folgendes verwenden:
function exist (json, modulid) { var ret = 0; $(json).each(function(index, data){ if(data.modulId == modulid) ret++; }) return ret > 0; }
quelle
Sie können JSONPath verwenden
So etwas machen:
results = JSONPath(null, TestObj, "$..[?(@.id=='A')]")
Beachten Sie, dass JSONPath ein Array von Ergebnissen zurückgibt
(Ich habe den Ausdruck "$ .. [? (@. Id == 'A')]" übrigens nicht getestet. Vielleicht muss er mit Hilfe einer Browserkonsole verfeinert werden.)
quelle
Eine weitere Option, die ich erwähnen wollte, ist, dass Sie Ihre Daten in XML konvertieren und dann so verwenden können,
jQuery.find(":id='A'")
wie Sie es möchten.Zu diesem Zweck gibt es jQuery-Plugins wie json2xml .
Wahrscheinlich ist der Konvertierungsaufwand nicht wert, aber das sind einmalige Kosten für statische Daten, daher kann dies nützlich sein.
quelle