recorrer objetos objeto imprimir elemento dinamico crear buscar array agregar javascript arrays object recursion data-manipulation

javascript - imprimir - Acceder/procesar(anidados) objetos, arrays o JSON



recorrer array de objetos javascript (20)

Tengo una estructura de datos anidada que contiene objetos y matrices. ¿Cómo puedo extraer la información, es decir, acceder a un valor específico o múltiple (o claves)?

Por ejemplo:

var data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] };

¿Cómo puedo acceder al name del segundo elemento en los items ?


Preliminares

JavaScript tiene un solo tipo de datos que puede contener varios valores: Objeto . Una matriz es una forma especial de objeto.

(Llano) Los objetos tienen la forma

{key: value, key: value, ...}

Las matrices tienen la forma

[value, value, ...]

Tanto las matrices como los objetos exponen una key -> value estructura de key -> value . Las claves en una matriz deben ser numéricas, mientras que cualquier cadena se puede usar como clave en los objetos. Los pares clave-valor también se denominan "propiedades" .

Se puede acceder a las propiedades usando notación de puntos.

const value = obj.someProperty;

o notación de corchetes , si el nombre de la propiedad no sería un nombre de identificador de JavaScript válido [espec.] , o si el nombre es el valor de una variable:

// the space is not a valid character in identifier names const value = obj["some Property"]; // property name as variable const name = "some Property"; const value = obj[name];

Por esa razón, solo se puede acceder a los elementos de la matriz utilizando la notación de corchetes:

const value = arr[5]; // arr.5 would be a syntax error // property name / index as variable const x = 5; const value = arr[x];

Espera ... ¿qué pasa con JSON?

JSON es una representación textual de datos, al igual que XML, YAML, CSV y otros. Para trabajar con dichos datos, primero se debe convertir a tipos de datos de JavaScript, es decir, matrices y objetos (y se explicó cómo trabajar con ellos). ¿Cómo analizar JSON se explica en la pregunta Parse JSON en JavaScript? .

Material de lectura adicional

Cómo acceder a matrices y objetos es un conocimiento fundamental de JavaScript y, por lo tanto, es recomendable leer la Guía de JavaScript de MDN , especialmente las secciones

Accediendo a estructuras de datos anidadas.

Una estructura de datos anidada es una matriz u objeto que se refiere a otras matrices u objetos, es decir, sus valores son matrices u objetos. Se puede acceder a dichas estructuras aplicando consecutivamente la notación de puntos o corchetes.

Aquí hay un ejemplo:

const data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] };

Supongamos que queremos acceder al name del segundo elemento.

Aquí es cómo podemos hacerlo paso a paso:

Como podemos ver, los data son un objeto, por lo tanto, podemos acceder a sus propiedades usando la notación de puntos. La propiedad de los items se accede de la siguiente manera:

data.items

El valor es una matriz, para acceder a su segundo elemento, tenemos que usar la notación de corchete:

data.items[1]

Este valor es un objeto y usamos la notación de puntos nuevamente para acceder a la propiedad del name . Así que eventualmente obtenemos:

const item_name = data.items[1].name;

Alternativamente, podríamos haber usado la notación de corchetes para cualquiera de las propiedades, especialmente si el nombre contenía caracteres que lo habrían invalidado para el uso de la notación de puntos:

const item_name = data[''items''][1][''name''];

¿Estoy tratando de acceder a una propiedad pero solo vuelvo undefined ?

La mayoría de las veces, cuando se está quedando undefined , el objeto / matriz simplemente no tiene una propiedad con ese nombre.

const foo = {bar: {baz: 42}}; console.log(foo.baz); // undefined

Utilice console.log o console.dir e inspeccione la estructura del objeto / matriz. La propiedad a la que intenta acceder puede estar realmente definida en un objeto / matriz anidado.

console.log(foo.bar.baz); // 42

¿Qué pasa si los nombres de las propiedades son dinámicos y no los conozco de antemano?

Si los nombres de las propiedades son desconocidos o queremos acceder a todas las propiedades de un objeto / elementos de una matriz, podemos usar el bucle for for...in [MDN] para objetos y el bucle for [MDN] para que las matrices se repitan en todos propiedades / elementos.

Objetos

Para iterar sobre todas las propiedades de los data , podemos iterar sobre el objeto así:

for (const prop in data) { // `prop` contains the name of each property, i.e. `''code''` or `''items''` // consequently, `data[prop]` refers to the value of each property, i.e. // either `42` or the array }

Dependiendo de dónde provenga el objeto (y qué quiere hacer), es posible que tenga que probar en cada iteración si la propiedad es realmente una propiedad del objeto, o si es una propiedad heredada. Puede hacer esto con Object#hasOwnProperty [MDN] .

Como alternativa a for...in con hasOwnProperty , puede usar Object.keys [MDN] para obtener una matriz de nombres de propiedades :

Object.keys(data).forEach(function(prop) { // `prop` is the property name // `data[prop]` is the property value });

Arrays

Para iterar sobre todos los elementos de la matriz data.items , usamos un bucle for :

for(let i = 0, l = data.items.length; i < l; i++) { // `i` will take on the values `0`, `1`, `2`,..., i.e. in each iteration // we can access the next element in the array with `data.items[i]`, example: // // var obj = data.items[i]; // // Since each element is an object (in our example), // we can now access the objects properties with `obj.id` and `obj.name`. // We could also use `data.items[i].id`. }

También se puede utilizar for...in iterar sobre matrices, pero hay razones por las que esto debe evitarse: ¿Por qué ''para (elemento var en la lista)'' con matrices se considera una mala práctica en JavaScript? .

Con la creciente compatibilidad con el navegador de ECMAScript 5, el método de matriz para forEach [MDN] se convierte en una alternativa interesante también:

data.items.forEach(function(value, index, array) { // The callback is executed for each element in the array. // `value` is the element itself (equivalent to `array[index]`) // `index` will be the index of the element in the array // `array` is a reference to the array itself (i.e. `data.items` in this case) });

En entornos compatibles con ES2015 (ES6), también puede usar el bucle for...of [MDN] , que no solo funciona para matrices, sino también para cualquier iterable :

for (const item of data.items) { // `item` is the array element, **not** the index }

En cada iteración, for...of directamente nos da el siguiente elemento de lo iterable, no hay "índice" para acceder o usar.

¿Qué pasa si la "profundidad" de la estructura de datos es desconocida para mí?

Además de las claves desconocidas, la "profundidad" de la estructura de datos (es decir, cuántos objetos anidados) tiene, también podría ser desconocida. Cómo acceder a propiedades profundamente anidadas generalmente depende de la estructura de datos exacta.

Pero si la estructura de datos contiene patrones repetitivos, por ejemplo, la representación de un árbol binario, la solución generalmente incluye el acceso recursivo [Wikipedia] a cada nivel de la estructura de datos.

Aquí hay un ejemplo para obtener el primer nodo de hoja de un árbol binario:

function getLeaf(node) { if (node.leftChild) { return getLeaf(node.leftChild); // <- recursive call } else if (node.rightChild) { return getLeaf(node.rightChild); // <- recursive call } else { // node must be a leaf node return node; } } const first_leaf = getLeaf(root);

const root = { leftChild: { leftChild: { leftChild: null, rightChild: null, data: 42 }, rightChild: { leftChild: null, rightChild: null, data: 5 } }, rightChild: { leftChild: { leftChild: null, rightChild: null, data: 6 }, rightChild: { leftChild: null, rightChild: null, data: 7 } } }; function getLeaf(node) { if (node.leftChild) { return getLeaf(node.leftChild); } else if (node.rightChild) { return getLeaf(node.rightChild); } else { // node must be a leaf node return node; } } console.log(getLeaf(root).data);

Una forma más genérica de acceder a una estructura de datos anidada con claves y profundidad desconocidas es probar el tipo de valor y actuar en consecuencia.

Aquí hay un ejemplo que agrega todos los valores primitivos dentro de una estructura de datos anidada en una matriz (asumiendo que no contiene ninguna función). Si nos encontramos con un objeto (o matriz) simplemente llamamos a toArray nuevo en ese valor (llamada recursiva).

function toArray(obj) { const result = []; for (const prop in obj) { const value = obj[prop]; if (typeof value === ''object'') { result.push(toArray(value)); // <- recursive call } else { result.push(value); } } return result; }

const data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] }; function toArray(obj) { const result = []; for (const prop in obj) { const value = obj[prop]; if (typeof value === ''object'') { result.push(toArray(value)); } else { result.push(value); } } return result; } console.log(toArray(data));

Ayudantes

Dado que la estructura de un objeto complejo o matriz no es necesariamente obvia, podemos inspeccionar el valor en cada paso para decidir cómo seguir avanzando. console.log y console.dir nos ayudan a hacer esto. Por ejemplo (salida de la consola de Chrome):

> console.log(data.items) [ Object, Object ]

Aquí vemos que data.items es una matriz con dos elementos que son objetos. En la consola Chrome, los objetos pueden incluso expandirse e inspeccionarse inmediatamente.

> console.log(data.items[1]) Object id: 2 name: "bar" __proto__: Object

Esto nos dice que data.items[1] es un objeto, y después de expandirlo, vemos que tiene tres propiedades, id , name y __proto__ . Esta última es una propiedad interna utilizada para la cadena prototipo del objeto. Sin embargo, la cadena de prototipos y la herencia están fuera del alcance de esta respuesta.


The Underscore js Way

Que es una biblioteca de JavaScript que proporciona una gran cantidad de ayudantes útiles de functional programming sin extender ningún objeto incorporado.

Solución:

var data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] }; var item = _.findWhere(data.items, { id: 2 }); if (!_.isUndefined(item)) { console.log(''NAME =>'', item.name); } //using find - var item = _.find(data.items, function(item) { return item.id === 2; }); if (!_.isUndefined(item)) { console.log(''NAME =>'', item.name); }


A veces, puede ser conveniente acceder a un objeto anidado utilizando una cadena. El enfoque simple es el primer nivel, por ejemplo.

var obj = { hello: "world" }; var key = "hello"; alert(obj[key]);//world

Pero a menudo este no es el caso del json complejo. A medida que json se vuelve más complejo, los enfoques para encontrar valores dentro del json también se vuelven complejos. Lo mejor es un enfoque recursivo para navegar por el json, y cómo se aproveche esa recursión dependerá del tipo de datos que se busquen. Si hay sentencias condicionales involucradas, una búsqueda json puede ser una buena herramienta para usar.

Si ya se conoce la propiedad a la que se accede, pero la ruta es compleja, por ejemplo, en este objeto

var obj = { arr: [ { id: 1, name: "larry" }, { id: 2, name: "curly" }, { id: 3, name: "moe" } ] };

Y sabe que desea obtener el primer resultado de la matriz en el objeto, tal vez le gustaría usar

var moe = obj["arr[0].name"];

Sin embargo, eso causará una excepción ya que no hay propiedad del objeto con ese nombre. La solución para poder usar esto sería aplanar el aspecto del árbol del objeto. Esto se puede hacer recursivamente.

function flatten(obj){ var root = {}; (function tree(obj, index){ var suffix = toString.call(obj) == "[object Array]" ? "]" : ""; for(var key in obj){ if(!obj.hasOwnProperty(key))continue; root[index+key+suffix] = obj[key]; if( toString.call(obj[key]) == "[object Array]" )tree(obj[key],index+key+suffix+"["); if( toString.call(obj[key]) == "[object Object]" )tree(obj[key],index+key+suffix+"."); } })(obj,""); return root; }

Ahora, el objeto complejo puede ser aplanado.

var obj = previous definition; var flat = flatten(obj); var moe = flat["arr[0].name"];//moe

Aquí se muestra una jsFiddle Demo de jsFiddle Demo de este enfoque.


Accediendo dinámicamente al objeto de múltiples niveles.

var obj = { name: "salut", subobj: { subsubobj: { names: "I am sub sub obj" } } }; var level = "subobj.subsubobj.names"; level = level.split("."); var currentObjState = obj; for (var i = 0; i < level.length; i++) { currentObjState = currentObjState[level[i]]; } console.log(currentObjState);

Fiddle de trabajo: https://jsfiddle.net/andreitodorut/3mws3kjL/


En caso de que esté intentando acceder a un item de la estructura de ejemplo por id o name , sin saber su posición en la matriz, la forma más sencilla de hacerlo sería usar la biblioteca underscore.js :

var data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] }; _.find(data.items, function(item) { return item.id === 2; }); // Object {id: 2, name: "bar"}

Desde mi experiencia, usar funciones de orden superior en lugar de for o for for..in loops da como resultado un código que es más fácil de razonar y, por lo tanto, más fácil de mantener.

Sólo mis 2 centavos.


Esta pregunta es bastante antigua, así como una actualización contemporánea. Con el inicio de ES2015, existen alternativas para obtener una retención de los datos que necesita. Ahora hay una característica llamada destrucción de objetos para acceder a objetos anidados.

const data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] }; const { items: [, { name: secondName }] } = data; console.log(secondName);

El ejemplo anterior crea una variable llamada secondName partir de la clave de name de una matriz llamada items solitarios , dice que se omite el primer objeto de la matriz.

En particular, es probable que sea excesivo para este ejemplo, ya que el acceso a una matriz simple es más fácil de leer, pero resulta útil cuando se separan los objetos en general.

Esta es una introducción muy breve a su caso de uso específico, la desestructuración puede ser una sintaxis inusual a la que debe acostumbrarse al principio. Recomiendo leer la documentación de Asignación de destrucción de Mozilla para obtener más información.


Los objetos y las matrices tienen muchos métodos integrados que pueden ayudarlo con el procesamiento de datos.

Nota: en muchos de los ejemplos estoy usando funciones de flecha . Son similares a las expresiones de función , pero vinculan el valor léxicamente.

Object.keys() , Object.values() (ES 2017) y Object.entries() (ES 2017)

Object.keys() devuelve una matriz de claves de objeto, Object.values() devuelve una matriz de valores de objeto, y Object.entries() devuelve una matriz de claves de objeto y los valores correspondientes en un formato [key, value] .

const obj = { a: 1 ,b: 2 ,c: 3 } console.log(Object.keys(obj)) // [''a'', ''b'', ''c''] console.log(Object.values(obj)) // [1, 2, 3] console.log(Object.entries(obj)) // [[''a'', 1], [''b'', 2], [''c'', 3]]

Object.entries() con un bucle for-of y asignación de desestructuración

const obj = { a: 1 ,b: 2 ,c: 3 } for (const [key, value] of Object.entries(obj)) { console.log(`key: ${key}, value: ${value}`) }

Es muy conveniente iterar el resultado de Object.entries() con un bucle for-of y una asignación de desestructuración .

El bucle for-of le permite iterar elementos de matriz. La sintaxis es for (const element of array) (podemos reemplazar const con var o let , pero es mejor usar const si no pretendemos modificar el element ).

La asignación de destrucción le permite extraer valores de una matriz o un objeto y asignarlos a variables. En este caso const [key, value] significa que, en lugar de asignar la matriz [key, value] al element , asignamos el primer elemento de esa matriz a la key y el segundo elemento al value . Es equivalente a esto:

for (const element of Object.entries(obj)) { const key = element[0] ,value = element[1] }

Como puede ver, la desestructuración hace esto mucho más simple.

Array.prototype.every() y Array.prototype.some()

El método every() devuelve true si la función de devolución de llamada especificada devuelve true para cada elemento de la matriz. El método some() devuelve true si la función de devolución de llamada especificada devuelve true para algún elemento (al menos uno).

const arr = [1, 2, 3] // true, because every element is greater than 0 console.log(arr.every(x => x > 0)) // false, because 3^2 is greater than 5 console.log(arr.every(x => Math.pow(x, 2) < 5)) // true, because 2 is even (the remainder from dividing by 2 is 0) console.log(arr.some(x => x % 2 === 0)) // false, because none of the elements is equal to 5 console.log(arr.some(x => x === 5))

Array.prototype.find() y Array.prototype.filter()

Los métodos find() devuelven el primer elemento que satisface la función de devolución de llamada proporcionada. El método filter() devuelve una matriz de todos los elementos que satisface la función de devolución de llamada proporcionada.

const arr = [1, 2, 3] // 2, because 2^2 !== 2 console.log(arr.find(x => x !== Math.pow(x, 2))) // 1, because it''s the first element console.log(arr.find(x => true)) // undefined, because none of the elements equals 7 console.log(arr.find(x => x === 7)) // [2, 3], because these elements are greater than 1 console.log(arr.filter(x => x > 1)) // [1, 2, 3], because the function returns true for all elements console.log(arr.filter(x => true)) // [], because none of the elements equals neither 6 nor 7 console.log(arr.filter(x => x === 6 || x === 7))

Array.prototype.map()

El método map() devuelve una matriz con los resultados de llamar a una función de devolución de llamada proporcionada en los elementos de la matriz.

const arr = [1, 2, 3] console.log(arr.map(x => x + 1)) // [2, 3, 4] console.log(arr.map(x => String.fromCharCode(96 + x))) // [''a'', ''b'', ''c''] console.log(arr.map(x => x)) // [1, 2, 3] (no-op) console.log(arr.map(x => Math.pow(x, 2))) // [1, 4, 9] console.log(arr.map(String)) // [''1'', ''2'', ''3'']

Array.prototype.reduce()

El método reduce reduce() reduce una matriz a un solo valor llamando a la función de devolución de llamada provista con dos elementos.

const arr = [1, 2, 3] // Sum of array elements. console.log(arr.reduce((a, b) => a + b)) // 6 // The largest number in the array. console.log(arr.reduce((a, b) => a > b ? a : b)) // 3

El método reduce() toma un segundo parámetro opcional, que es el valor inicial. Esto es útil cuando la matriz a la que llama reduce() puede tener cero o un elemento. Por ejemplo, si quisiéramos crear una función sum() que tome una matriz como argumento y devuelva la suma de todos los elementos, podríamos escribirla así:

const sum = arr => arr.reduce((a, b) => a + b, 0) console.log(sum([])) // 0 console.log(sum([4])) // 4 console.log(sum([2, 5])) // 7


No creo que el interrogador solo se refiera a un objeto anidado de un nivel, por lo que presento la siguiente demostración para demostrar cómo acceder al nodo del objeto json profundamente anidado. De acuerdo, encontremos el nodo con id ''5''.

var data = { code: 42, items: [{ id: 1, name: ''aaa'', items: [{ id: 3, name: ''ccc'' }, { id: 4, name: ''ddd'' }] }, { id: 2, name: ''bbb'', items: [{ id: 5, name: ''eee'' }, { id: 6, name: ''fff'' }] }] }; var jsonloop = new JSONLoop(data, ''id'', ''items''); jsonloop.findNodeById(data, 5, function(err, node) { if (err) { document.write(err); } else { document.write(JSON.stringify(node, null, 2)); } });

<script src="https://rawgit.com/dabeng/JSON-Loop/master/JSONLoop.js"></script>


Para acceder a un atributo anidado, debe especificar su nombre y luego buscar en el objeto.

Si ya conoce la ruta exacta, puede codificarla en su script de la siguiente manera:

data[''items''][1][''name'']

estos también funcionan -

data.items[1].name data[''items''][1].name data.items[1][''name'']

Cuando no sabe el nombre exacto de antemano, o un usuario es el que le proporciona el nombre. Luego se requiere buscar dinámicamente a través de la estructura de datos. Algunos sugirieron aquí que la búsqueda se puede hacer usando un bucle for , pero hay una manera muy simple de recorrer una ruta usando Array.prototype.reduce() .

const data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] } const path = [ ''items'', ''1'', ''name''] let result = path.reduce((a,v) => a[v], data)

La ruta es una forma de decir: primero tome el objeto con items clave, que es una matriz. Luego tome el primer elemento (arrays de índice 0). Por último, tome el objeto con el name clave en ese elemento de la matriz, que es la bar cadena.

Si tiene una ruta muy larga, incluso podría utilizar String.split para facilitar todo esto:

''items.1.name''.split(''.'').reduce((a,v) => a[v], data)

Esto es simplemente JavaScript, sin usar bibliotecas de terceros como jQuery o lodash.


Podrías usar la función lodash _get :

var object = { ''a'': [{ ''b'': { ''c'': 3 } }] }; _.get(object, ''a[0].b.c''); // => 3


Por si acaso, cualquiera que visite esta pregunta en 2017 o más adelante y busque una manera fácil de recordar , aquí hay una publicación de blog elaborada sobre Acceso a objetos anidados en JavaScript sin ser engañada por

No se puede leer la propiedad ''foo'' del error indefinido

1. Patrón de acceso de objeto anidado de Oliver Steele

La forma más fácil y limpia es usar el patrón de acceso a objetos anidados de Oliver Steele

const name = ((user || {}).personalInfo || {}).name;

Con esta notación, nunca te encontrarás con

No se puede leer la propiedad ''nombre'' de undefined .

Básicamente, verifica si el usuario existe, si no, crea un objeto vacío sobre la marcha. De esta manera, siempre se podrá acceder a la siguiente clave de nivel desde un objeto existente o desde un objeto vacío , pero nunca desde indefinido.

2. Acceder a objetos anidados utilizando la matriz de reducción

Para poder acceder a matrices anidadas, puede escribir su propia utilidad de reducción de matriz.

const getNestedObject = (nestedObj, pathArr) => { return pathArr.reduce((obj, key) => (obj && obj[key] !== ''undefined'') ? obj[key] : undefined, nestedObj); } // pass in your object structure as array elements const name = getNestedObject(user, [''personalInfo'', ''name'']); // to access nested array, just pass in array index as an element the path array. const city = getNestedObject(user, [''personalInfo'', ''addresses'', 0, ''city'']); // this will return the city from the first address item.

También hay un excelente typy tipo de biblioteca typy que hace todo esto por ti.


Prefiero JQuery. Es más limpio y fácil de leer.

$.each($.parseJSON(data), function (key, value) { alert(value.<propertyname>); });


Pregunta antigua pero como nadie mencionó lodash (solo subrayar).

En caso de que ya esté utilizando lodash en su proyecto, creo que es una forma elegante de hacerlo en un ejemplo complejo:

Opta 1

_.get(response, [''output'', ''fund'', ''data'', ''0'', ''children'', ''0'', ''group'', ''myValue''], '''')

igual que:

Opta 2

response.output.fund.data[0].children[0].group.myValue

La diferencia entre la primera y la segunda opción es que en la Opción 1, si tiene una de las propiedades faltantes (no definidas) en la ruta, no recibe un error, le devuelve el tercer parámetro.

Para array de filtro, lodash tiene _.find() pero prefiero usar el filter() regular filter() . Pero sigo pensando que el método anterior _.get() es muy útil cuando se trabaja con datos realmente complejos. Me enfrenté en el pasado a API muy complejas y fue útil!

Espero que pueda ser útil para quienes buscan opciones para manipular datos realmente complejos que implica el título.


Se puede acceder de esta manera.

data.items[1].name

o

data["items"][1]["name"]

Ambas formas son iguales.


Si está buscando uno o más objetos que cumplan con ciertos criterios, tiene algunas opciones utilizando query-js

//will return all elements with an id larger than 1 data.items.where(function(e){return e.id > 1;}); //will return the first element with an id larger than 1 data.items.first(function(e){return e.id > 1;}); //will return the first element with an id larger than 1 //or the second argument if non are found data.items.first(function(e){return e.id > 1;},{id:-1,name:""});

También hay un single y un singleOrDefault que funcionan como el first y el first firstOrDefault respectivamente. La única diferencia es que lanzarán si se encuentra más de una coincidencia.

Para una explicación más detallada de query-js, puede comenzar con esta post


Un enfoque pythonic, recursivo y funcional para desentrañar árboles JSON arbitrarios:

handlers = { list: iterate, dict: delve, str: emit_li, float: emit_li, } def emit_li(stuff, strong=False): emission = ''<li><strong>%s</strong></li>'' if strong else ''<li>%s</li>'' print(emission % stuff) def iterate(a_list): print(''<ul>'') map(unravel, a_list) print(''</ul>'') def delve(a_dict): print(''<ul>'') for key, value in a_dict.items(): emit_li(key, strong=True) unravel(value) print(''</ul>'') def unravel(structure): h = handlers[type(structure)] return h(structure) unravel(data)

donde los datos son una lista de python (analizados a partir de una cadena de texto JSON):

data = [ {''data'': {''customKey1'': ''customValue1'', ''customKey2'': {''customSubKey1'': {''customSubSubKey1'': ''keyvalue''}}}, ''geometry'': {''location'': {''lat'': 37.3860517, ''lng'': -122.0838511}, ''viewport'': {''northeast'': {''lat'': 37.4508789, ''lng'': -122.0446721}, ''southwest'': {''lat'': 37.3567599, ''lng'': -122.1178619}}}, ''name'': ''Mountain View'', ''scope'': ''GOOGLE'', ''types'': [''locality'', ''political'']} ]


Usar JSONPath sería una de las soluciones más flexibles si está dispuesto a incluir una biblioteca: https://github.com/s3u/JSONPath (nodo y navegador)

Para su caso de uso, la ruta json sería:

$..items[1].name

asi que:

var secondName = jsonPath.eval(data, "$..items[1].name");


La función grep de jQuery te permite filtrar a través de una matriz:

var data = { code: 42, items: [{ id: 1, name: ''foo'' }, { id: 2, name: ''bar'' }] }; $.grep(data.items, function(item) { if (item.id === 2) { console.log(item.id); //console id of item console.log(item.name); //console name of item console.log(item); //console item object return item; //returns item object } }); // Object {id: 2, name: "bar"}

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


Usar lodash sería una buena solución

Ex:

var object = { ''a'': { ''b'': { ''c'': 3 } } }; _.get(object, ''a.b.c''); // => 3


var ourStorage = { "desk": { "drawer": "stapler" }, "cabinet": { "top drawer": { "folder1": "a file", "folder2": "secrets" }, "bottom drawer": "soda" } }; ourStorage.cabinet["top drawer"].folder2; // Outputs -> "secrets"

o

//parent.subParent.subsubParent["almost there"]["final property"]

Básicamente, use un punto entre cada descendiente que se despliega debajo de él y cuando tenga nombres de objetos hechos de dos cadenas, debe usar la notación ["nombre de obj"]. De lo contrario, solo un punto sería suficiente;

Fuente: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-objects

Para agregar a esto, el acceso a las Matrices anidadas sería así:

var ourPets = [ { animalType: "cat", names: [ "Meowzer", "Fluffy", "Kit-Cat" ] }, { animalType: "dog", names: [ "Spot", "Bowser", "Frankie" ] } ]; ourPets[0].names[1]; // Outputs "Fluffy" ourPets[1].names[0]; // Outputs "Spot"

Fuente: https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/basic-javascript/accessing-nested-arrays/