70 votes

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

Similaire à La question de brnwdrng Je cherche un moyen d'effectuer une recherche dans un objet de type JSON.
en supposant que la structure de mon objet soit comme ça :

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 comme :

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

mais rien ne semble fonctionner.

Quelqu'un peut-il trouver un moyen de récupérer un élément en fonction de certains critères sans utiliser "each" ?

117voto

Box9 Points 41987

JQuery ne fonctionne pas sur les littéraux d'objets simples. Vous pouvez utiliser la fonction ci-dessous de manière similaire pour rechercher tous les 'id' (ou toute autre propriété), quelle que soit sa 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 ça :

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

47voto

davenpcj Points 3424

La solution purement javascript est meilleure, mais une solution jQuery serait d'utiliser la fonction jQuery grep et/ou carte méthodes. Probablement pas beaucoup mieux que d'utiliser $.each

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

o

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

Renvoie un tableau des objets correspondants, ou des valeurs recherchées dans le cas de map. Vous pouvez peut-être faire ce que vous voulez en utilisant simplement ces éléments.

Mais dans cet exemple, il faudrait faire de la récursion, 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 purement 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;
}

Essentiellement la même chose que la réponse de Box9, mais en utilisant les fonctions utilitaires de jQuery lorsque cela est utile.

--------

4voto

byedissident Points 31

Cela fonctionne pour moi avec [{"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;
}

3voto

Raugaral Points 111

Pour un json à une dimension, vous pouvez utiliser ceci :

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

2voto

matt Points 412

Vous pouvez utiliser JSONPath

Faisant 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 faut-il l'affiner avec l'aide d'une console de navigateur)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X