Использовать jQuery find() для объекта JSON
Как и вопрос brnwdrng, я ищу способ поиска через JSON-подобный объект.
предполагая, что моя структура объекта такова:
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."
}]
};
Я хотел бы получить объект с id = "A".
Я пробовал все такие вещи, как:
$(TestObj.find(":id='A'"))
но ничего не работает.
Может ли кто-нибудь подумать о способе получения элемента на основе некоторых критериев, не используя "каждый"?
Ответы
Ответ 1
jQuery не работает с литералами простых объектов. Вы можете использовать следующую функцию аналогично поиску всего "id (или любого другого свойства), независимо от его глубины в объекте:
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;
}
Используйте так:
getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects
Ответ 2
Чистое решение javascript лучше, но способ jQuery - использовать jQuery grep и/или map.
Вероятно, не намного лучше, чем использовать $.each
jQuery.grep(TestObj, function(obj) {
return obj.id === "A";
});
или
jQuery.map(TestObj, function(obj) {
if(obj.id === "A")
return obj; // or return obj.name, whatever.
});
Возвращает массив совпадающих объектов или возвращаемых значений в случае карты. Можете быть в состоянии сделать то, что вы хотите, просто используя их.
Но в этом примере вам нужно будет сделать некоторую рекурсию, потому что данные не являются плоским массивом, и мы принимаем произвольные структуры, ключи и значения, как это делают чистые javascript-решения.
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;
}
По существу то же самое, что и в ответе Box9, но с полезными функциями утилиты jQuery.
········
Ответ 3
Это работает для меня на [{ "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;
}
Ответ 4
Для одного измерения json вы можете использовать это:
function exist (json, modulid) {
var ret = 0;
$(json).each(function(index, data){
if(data.modulId == modulid)
ret++;
})
return ret > 0;
}
Ответ 5
Вы можете использовать JSONPath
Выполнение чего-то подобного:
results = JSONPath(null, TestObj, "$..[?(@.id=='A')]")
Обратите внимание, что JSONPath возвращает массив результатов
(Я не тестировал выражение "$.. [? (@. id == 'A')]" btw. Возможно, его нужно настроить с помощью консоли браузера)
Ответ 6
Еще один вариант, который я хотел упомянуть, вы могли бы преобразовать свои данные в XML, а затем использовать jQuery.find(":id='A'")
так, как вам хотелось.
Для этого есть плагины jQuery, например json2xml.
Вероятно, не стоит накладных расходов на конвертацию, но это одноразовая стоимость для статических данных, поэтому может быть полезно.