используйте jQuery's find () для объекта JSON - PullRequest
70 голосов
/ 14 февраля 2011

Как и вопрос 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'"))

но, похоже, ничего не работает.

Может ли кто-нибудь придумать способ получения предмета по некоторым критериям, не используя «каждый»?

Ответы [ 6 ]

117 голосов
/ 14 февраля 2011

jQuery не работает с обычными объектными литералами. Вы можете использовать приведенную ниже функцию аналогичным образом для поиска всех идентификаторов (или любого другого свойства), независимо от его глубины в объекте:

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
45 голосов
/ 11 августа 2011

Чистое решение на 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, где это полезно.·

4 голосов
/ 21 февраля 2012

Это работает для меня [{"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;
}
3 голосов
/ 18 ноября 2014

Для одного измерения JSON вы можете использовать это:

function exist (json, modulid) {
    var ret = 0;
    $(json).each(function(index, data){
        if(data.modulId == modulid)
            ret++;
    })
    return ret > 0;
}
1 голос
/ 17 ноября 2015

Вы можете использовать JSONPath

Делая что-то вроде этого:

results = JSONPath(null, TestObj, "$..[?(@.id=='A')]")

Обратите внимание, что JSONPath возвращает массив результатов

(кстати, я не проверял выражение "$ .. [? (@. Id == 'A')]". Возможно, его нужно настроить с помощью консоли браузера)

0 голосов
/ 11 августа 2011

Еще один вариант, который я хотел упомянуть: вы можете конвертировать ваши данные в XML, а затем использовать jQuery.find(":id='A'") так, как вы хотели.

Для этого есть плагины jQuery, например json2xml ,

Вероятно, не стоит затрат на конвертацию, но это одноразовая плата за статические данные, поэтому она может быть полезна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...