web-dev-qa-db-fra.com

utiliser la fonction find () de jQuery sur un objet JSON

Semblable à question de brnwdrng , je cherche un moyen de rechercher dans un objet de type JSON.
en supposant que la structure de mon objet ressemble à ceci:

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."
    }]
};

Je voudrais obtenir un objet avec id = "A".

J'ai essayé toutes sortes de choses telles que:

$(TestObj.find(":id='A'"))

mais rien ne semble fonctionner.

Quelqu'un peut-il penser à un moyen de récupérer un article en fonction de certains critères sans utiliser "chacun"?

70
J. Ed

jQuery ne fonctionne pas sur les littéraux d'objets simples. Vous pouvez utiliser la fonction ci-dessous de la même manière pour rechercher tous les identifiants (ou toute autre propriété), quelle que soit leur profondeur dans l'objet:

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;
}

Utilisez comme si:

getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects
117
David Tang

La solution javascript pure est préférable, mais une méthode jQuery consisterait à utiliser les méthodes jQuery grep et/ou map . Probablement pas beaucoup mieux que d'utiliser $ .each

jQuery.grep(TestObj, function(obj) {
    return obj.id === "A";
});

ou

jQuery.map(TestObj, function(obj) {
    if(obj.id === "A")
         return obj; // or return obj.name, whatever.
});

Retourne un tableau des objets correspondants, ou des valeurs recherchées dans le cas de la carte. Peut-être capable de faire ce que vous voulez simplement en utilisant ceux-ci.

Mais dans cet exemple, vous devrez faire de la récursivité, car les données ne sont pas un tableau plat et nous acceptons des structures, des clés et des valeurs arbitraires, comme le font les solutions javascript pures.

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;
}

Essentiellement identique à la réponse de Box9, mais l'utilisation des fonctions de l'utilitaire jQuery est utile.

········

45
davenpcj

Cela fonctionne pour moi sur [{"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
byedissident

Pour une dimension json, vous pouvez utiliser ceci:

function exist (json, modulid) {
    var ret = 0;
    $(json).each(function(index, data){
        if(data.modulId == modulid)
            ret++;
    })
    return ret > 0;
}
3
Raugaral

Vous pouvez utiliser JSONPath

Faire quelque chose comme ça:

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

Notez que JSONPath renvoie un tableau de résultats.

(Je n'ai pas testé l'expression "$ .. [? (@. Id == 'A')]" "btw. Peut-être a-t-elle besoin d'être ajustée à l'aide d'une console de navigateur)

1
matt