use find() de jQuery en un objeto JSON

Resuelto J. Ed asked hace 13 años • 6 respuestas

De manera similar a la pregunta de brnwdrng , estoy buscando una manera de buscar en un objeto similar a JSON.
suponiendo que la estructura de mi objeto es así:

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

Me gustaría obtener un objeto con id="A".

He probado todo tipo de cosas como:

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

Pero nada parece funcionar.

¿Alguien puede pensar en una forma de recuperar un elemento basándose en algunos criterios sin utilizar "cada uno"?

J. Ed avatar Feb 14 '11 19:02 J. Ed
Aceptado

jQuery no funciona con objetos literales simples. Puede utilizar la siguiente función de forma similar para buscar todos los 'id's (o cualquier otra propiedad), independientemente de su profundidad en el objeto:

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

Úselo así:

getObjects(TestObj, 'id', 'A'); // Returns an array of matching objects
David Tang avatar Feb 14 '2011 13:02 David Tang

La solución de JavaScript puro es mejor, pero una forma de jQuery sería utilizar los métodos jQuery grep y/o map . Probablemente no sea mucho mejor que usar $.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.
});

Devuelve una matriz de los objetos coincidentes o de los valores buscados en el caso del mapa. Podrías hacer lo que quieras simplemente usándolos.

Pero en este ejemplo tendría que hacer algo de recursividad, porque los datos no son una matriz plana y aceptamos estructuras, claves y valores arbitrarios, tal como lo hacen las soluciones de JavaScript puro.

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

Esencialmente lo mismo que la respuesta de Box9, pero utilizando las funciones de la utilidad jQuery cuando sea útil.

········

davenpcj avatar Aug 11 '2011 13:08 davenpcj

Esto funciona para mí en [{"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;
}
byedissident avatar Feb 20 '2012 22:02 byedissident

Para json de una dimensión puedes usar esto:

function exist (json, modulid) {
    var ret = 0;
    $(json).each(function(index, data){
        if(data.modulId == modulid)
            ret++;
    })
    return ret > 0;
}
Raugaral avatar Nov 18 '2014 08:11 Raugaral