use find() de jQuery en un objeto JSON
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"?
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
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.
········
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;
}
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;
}