usa el find () de jQuery en el objeto JSON

Similar a la pregunta de brnwdrng , estoy buscando una forma de buscar a través de 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 intentado todo tipo de cosas, como:

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

Pero nada parece funcionar.

¿Alguien puede pensar en una forma de recuperar un artículo basado en algunos criterios sin usar ‘cada’?

jQuery no funciona en literales de objeto simple. Puede utilizar la función siguiente 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 javascript pura es mejor, pero una forma jQuery sería usar 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ía ser capaz de hacer lo que quiera simplemente usando esos.

Pero en este ejemplo tendrías que hacer alguna recursión, porque los datos no son una matriz plana, y estamos aceptando estructuras, claves y valores arbitrarios, al igual que las soluciones puras de 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; } 

Esencialmente es lo mismo que la respuesta de Box9, pero el uso de las funciones de la utilidad jQuery es ú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 una dimensión json puedes usar esto:

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

Puedes usar JSONPath

Haciendo algo como esto:

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

Tenga en cuenta que JSONPath devuelve una matriz de resultados

(No he probado la expresión “$ .. [? (@. Id == ‘A’)]” Por cierto, debe ser ajustada con la ayuda de una consola de navegador)

Otra opción que quería mencionar es que puede convertir sus datos en XML y luego usar jQuery.find(":id='A'") la forma que desee.

Hay complementos de jQuery para ese efecto, como json2xml .

Probablemente no valga la pena la sobrecarga de conversión, pero ese es un costo de una sola vez para los datos estáticos, por lo que podría ser útil.