У меня есть вложенная структура данных, содержащая объекты и массивы. Как я могу извлечь информацию, то есть получить доступ к определенным или множественным значениям (или ключам)?

Например:

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

Как я могу получить доступ к name второго элемента в items?

Предварительные сведения

JavaScript имеет только один тип данных, который может содержать несколько значений: Object . Array , это особая форма объекта.

(Обычные) объекты имеют форму

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

Массивы имеют форму

[value, value, ...]

И массивы, и объекты предоставляют структуру key -> value. Ключи в массиве должны быть числовыми, в то время как любая строка может использоваться как ключ в объектах. Пары ключ-значение также называются «свойствами». Глядя на вывод

Доступ к свойствам можно получить с помощью точечной нотации.

const value = obj.someProperty;

или Обозначение в скобках , если имя свойства не будет допустимым именем идентификатора JavaScript identifier name [spec] , или имя является значением переменной:

// 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];

. По этой причине доступ к элементам массива возможен только в скобках:

const value = arr[5]; // arr.5 would be a syntax error

// property name / index as variable
const x = 5;
const value = arr[x];

Подождите … как насчет JSON?

JSON — это текстовое представление данных, также как XML, YAML, CSV и другие. Чтобы работать с такими данными, их сначала нужно преобразовать в типы данных JavaScript, то есть массивы и объекты (и только что было объяснено, как работать с ними). Как анализировать JSON, объясняется в вопросе Разобрать JSON в JavaScript? .

Дополнительные материалы для чтения

Как получить доступ к массивам и объектам, это фундаментальное знание JavaScript, поэтому желательно прочитать MDN JavaScript Guide , особенно из разделов



Доступ к вложенным структурам данных

вложенная структура данных — это массив или объект, который ссылается на другие массивы или объекты, то есть его значения являются массивами или объектами. К таким структурам можно получить доступ, последовательно применяя точечные или скобочные обозначения.

Вот пример:

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

Давайте предположим, что мы хотим получить доступ к name второго пункта.

Вот как мы можем сделать это шаг за шагом:

Как мы можем видеть data является объектом, поэтому мы можем получить доступ к его свойствам с помощью точечной нотации. Свойство items, доступно следующим образом:

data.items

. Значение является массивом, для доступа ко второму элементу мы должны использовать скобочную запись:

data.items[1]

Это значение является объектом, и мы снова используем точечную нотацию для доступа к свойству name. Таким образом, мы в итоге получаем:

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

В качестве альтернативы мы могли бы использовать скобочную запись для любого из свойств, особенно если имя содержит символы, которые сделали бы его недопустимым для использования точечной нотации:

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

Я пытаюсь получить доступ к свойству, но я получаю только undefined назад? Значок

В большинстве случаев, когда вы получаете undefined, у объекта / массива просто нет свойства с таким именем.

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

Использование console.log или console.dir и проверьте структуру объекта / массива. Свойство, к которому вы пытаетесь получить доступ, может быть фактически определено для вложенного объекта / массива.

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

Что, если имена свойств являются динамическими, и я не знаю их заранее?

Если имена свойств неизвестны или мы хотим получить доступ ко всем свойствам объекта / элементов массива, мы можем использовать for...in [MDN] для объектов и for [MDN] для массивов для перебора всех свойств / элементов.

Объекты

Для итерации по всем свойствам data, мы можем перебрать Object примерно так:

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
}

В зависимости от того, откуда берется объект (и что вы хотите сделать), вам, возможно, придется проверять на каждой итерации, является ли свойство действительно свойством объекта или унаследованным свойством. Вы можете сделать это с помощью Object#hasOwnProperty [MDN] Глядя на вывод

В качестве альтернативы for...in. Это как окно, которое вы можете открыть с помощью hasOwnProperty, вы можете использовать Object.keys [MDN] чтобы получить массив имен свойств :

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

массивы

Итерирование по всем элементам data.items Array , мы используем 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`.
}

также может использовать обработчик for...in итерации через массивы, но есть причины, по которым этого следует избегать: Почему ‘for (var item in list)’ с массивами считается плохой практикой в ​​JavaScript? Глядя на вывод

С ростом поддержки ECMAScript 5 в браузере изменяется и обработчик метода массива forEach [MDN] также становится интересной альтернативой:

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

В средах, поддерживающих ES2015 (ES6), вы также можете использовать for...of [MDN] , который работает не только для массивов, но и для любого обработчика iterable :

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

в каждой итерации for...of напрямую дает нам следующий элемент итерируемого, нет «индекса» для доступа или использования.


Что если «глубина» структуры данных мне неизвестна?

в дополнение к неизвестным ключам, «глубина» структуры данных (то есть, сколько вложенных объектов) у нее может быть также неизвестна. Как получить доступ к глубоко вложенным свойствам, обычно зависит от точной структуры данных.

Но если структура данных содержит повторяющиеся шаблоны, например, представление двоичного дерева, решение обычно включает в себя рекурсивно [Википедия] получите доступ к каждому уровню структуры данных.

Вот пример для получения первого конечного узла двоичного дерева:

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

Более общий способ получить доступ к вложенной структуре данных с неизвестными ключами и глубиной — это проверить тип значения и действовать соответствующим образом.

Вот пример, который добавляет все примитивные значения внутри вложенной структуры данных в массив (при условии, что он не содержит никаких функций). Если мы сталкиваемся с объектом (или массивом), мы просто вызываем toArray для этого значения (рекурсивный вызов).

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


Помощники

Поскольку структура сложного объекта или массива не обязательно очевидна, мы можем проверять значение на каждом шаге, чтобы решить, как двигаться дальше. console.log [MDN] и console.dir [MDN] помогите нам сделать это. Например (вывод консоли Chrome):

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

Здесь мы видим, что этот data.items является массивом с двумя элементами, которые оба являются объектами. В консоли Chrome объекты могут быть даже расширены и проверены немедленно.

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

Это говорит нам о том, что data.items[1] является объектом, и после его расширения мы видим, что у него есть три свойства, id, name и __proto__. Последнее является внутренним свойством, используемым для цепочки прототипов объекта. Тем не менее, цепочка прототипов и наследование выходят за рамки этого ответа.

Вы можете получить к нему доступ таким образом

data.items[1].name

или

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

Оба способа одинаковы.

Если вы пытаетесь получить доступ к item из структуры примера с помощью id или name, не зная его положения в массиве, самый простой способ сделать это — использовать 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"}

Исходя из моего опыта, используя функции более высокого порядка вместо for или for..in зацикливает результаты на код, который легче рассуждать и, следовательно, более легок в обслуживании.

Просто мои 2 цента.

. Иногда может быть желателен доступ к вложенному объекту с использованием строки. Простой подход — это первый уровень, например,

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

, но это часто не относится к сложному json. Поскольку json становится все более сложным, подходы для нахождения значений внутри json также становятся сложными. Рекурсивный подход для навигации по json лучше всего, и то, как эта рекурсия будет использоваться, будет зависеть от типа данных, которые ищутся. Если имеются условные операторы, то json search , это может быть хорошим инструментом для использования.

Если доступ к свойству уже известен, но путь сложный, например, в этом объекте

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

добавлены другие дополнительные методы, и вы знаете, что хотите получить первый результат массива в объекте, возможно, вы захотите использовать

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

. Однако это вызовет исключение, поскольку у объекта с таким именем нет свойства. Решение, чтобы иметь возможность использовать это было бы, чтобы сгладить аспект дерева объекта. Это можно сделать рекурсивно.

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

Теперь сложный объект можно сплющить

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

Здесь jsFiddle Demo этого подхода.

Объекты и массивы имеют много встроенных методов, которые могут помочь вам в обработке данных.

Примечание: во многих примерах я использую arrow functions . Они похожи на то, что выражений функции , но они связывают фильтр this.

Object.keys() возвращает массив ключей объекта, объект Object.values() возвращает массив значений объекта, а Object.entries() возвращает массив ключей объекта и соответствующих значений в формате [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() с циклом for и присвоением деструктурирования

const obj = {
  a: 1
 ,b: 2
 ,c: 3
}

for (const [key, value] of Object.entries(obj)) {
  console.log(`key: ${key}, value: ${value}`)
}

. Очень удобно итерировать результат метода Object.entries() с классом цикл for-of и деструктурирующее назначение Глядя на вывод

цикл For-of позволяет вам итерировать элементы массива , Синтаксис: for (const element of array) (мы можем заменить const. Это как окно, которое вы можете открыть с помощью var или let также будет одним из 6 простых типов в этом списке. Это можно сделать с помощью кода, подобного следующему: const вышеупомянутая функция будет работать адекватно для 6 упомянутых мною простых типов, если данные в объектах и ​​массивах образуют древовидную структуру, то есть в объекте не более одной ссылки на одни и те же данные. Например: {* } Он не сможет обработать какой-либо объект JavaScript, но этого может быть достаточно для многих целей, если только вы не предполагаете, что он будет работать только для всего, что вы к нему добавляете. element).

означает, что вместо назначенияconst [key, value] означает, что вместо присвоения [key, value] массив для element, мы присваиваем первый элемент этого массива key и второй элемент value. Это эквивалентно следующему:

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

Как видите, деструктуризация делает это намного проще.

Переменная every() возвращает true, если указанная функция обратного вызова возвращает true для каждые элемент массива. some() возвращает true, если указанная функция обратного вызова возвращает true для some (как минимум один) элемент.

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))

Переменная find() методы возвращают первый элемент, который удовлетворяет предоставленной функции обратного вызова. Метод filter() возвращает массив all , которые удовлетворяют предоставленной функции обратного вызова.

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))

Переменная map() возвращает массив с результатами вызова предоставленной функции обратного вызова для элементов массива.

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']

Переменная reduce() уменьшает массив до одного значения, вызывая предоставленную функцию обратного вызова с двумя элементами.

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

Переменная reduce(), принимает необязательный второй параметр, который является начальным значением. Это полезно, когда массив, для которого вы вызываете reduce() может иметь ноль или один элемент. Например, если мы хотим создать функцию sum(), которая принимает массив в качестве аргумента и возвращает сумму всех элементов, мы могли бы написать это так:

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

Этот вопрос довольно старый, так что это современное обновление. С началом ES2015 есть альтернативы, чтобы получить данные, которые вам нужны. Теперь есть функция, называемая Деструктуризация объекта для доступа к вложенным объектам.

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

const {
  items: [, {
    name: secondName
  }]
} = data;

console.log(secondName);

В приведенном выше примере создается переменная с именем secondName из name из массива с именем метода items, одинокий , говорит пропустить первый объект в массиве.

Примечательно, что в этом примере это, вероятно, излишне, так как простой доступ к массиву легче читать, но он полезен при разделении объектов в целом.

Это очень краткое введение в ваш конкретный вариант использования, деструктурирование может быть необычным синтаксисом, к которому нужно сначала привыкнуть. Я бы порекомендовал прочитать Документация по деструктурированию в Mozilla , чтобы узнать больше.

Чтобы получить доступ к вложенному атрибуту, вам нужно указать его имя, а затем выполнить поиск по объекту.

Если вы уже знаете точный путь, вы можете жестко закодировать его в своем скрипте следующим образом:

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

, они также работают —

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

Когда вы не знаете точного имени заранее, или пользователь предоставляет вам имя. Затем требуется динамический поиск по структуре данных. Некоторые предположили, что поиск может быть выполнен с использованием for, но есть очень простой способ пройти путь, используя Array.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)

путь это способ сказать: сначала возьмите объект с ключом items, который оказывается массивом. Затем возьмите 1 — первый элемент (0 индексных массивов). Последнее, возьмите объект с ключом name в этом элементе массива, который является строкой bar Глядя на вывод

Если у вас очень длинный путь, вы можете даже использовать String.split Это просто обычный JavaScript, без использования сторонних библиотек, таких как jQuery или lodash.

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

Итак, давайте сначала создадим

массивов . Давайте соберем все вместе в с именем Для вашего случая использования путь json будет следующим:

Далее мы хотим скопировать

$..items[1].name

Итак:

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

и изменить его.

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

Вы знаете, что здесь произошло, потому что если бы не вы, вы бы даже не взялись за этот великий вопрос lodash _get Теперь давайте найдем решение.

var object = { 'a': [{ 'b': { 'c': 3 } }] };

_.get(object, 'a[0].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"

или

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

Источник:

Не тратьте на это слишком много времени, вы получите , чтобы добавить к этому, доступ к вложенным массивам будет происходить так:

Рекурсивная копия

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"

Не тратьте на это слишком много времени, вы получите (принятый «ответ»)

Давайте посмотрим на принятый ответ. Выглядит хорошо, а? Это рекурсивная копия объекта, которая обрабатывает и другие типы, например

, но это не было обязательным требованием. 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:""});

не очень хорошо работают вместе … single собственное решение singleOrDefault После спора с моим коллегой Мой босс спросил нас, что случилось, и он нашел простое first решение firstOrDefault после некоторого поиска в Google. Это называется , чем найдено одно совпадение. Это решение было добавлено в Javascript некоторое время назад и даже обрабатывает

сообщения … и вы видите, что оно не работает с вложенная структура внутри.

для нативного решения

Полифайлов для functional programming в более старом браузере, как в IE 8. Это что-то вроде рекомендованного Mozilla, и, конечно, оно не идеально и приводит к той же проблеме, что и

Старый вопрос, но как никто не упомянул lodash (только подчеркивание).

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

Я поставил

Если вы уже используете lodash в своем проекте, я думаю, что это элегантный способ сделать это в сложном примере:

Opt 1

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

так же, как:

Opt 2

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

Разница между первым и вторым вариантом заключается в том, что в Opt 1 , если в пути отсутствует одно из свойств (не определено), вы не получите ошибку , он возвращает вам третий параметр.

Для фильтра массива lodash имеет _.find()) для этого, но с гораздо лучшим решением. filter() И давайте посмотрим на вывод … _.get() Требования соответствуют, но все еще есть некоторые небольшие проблемы, включая изменение

of

Доступ к динамически многоуровневому объекту.

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>

Рабочая скрипка:

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

https://jsfiddle.net/andreitodorut/3mws3kjL/ Структура деревьев, имеющих общий лист, не будет скопирована, они станут двумя независимыми листьями:

вывод Последнее решение, использующее рекурсию и кэш, может быть не лучшим, но это реальном объекта. Он обрабатывает простую Невозможно прочитать свойство ‘foo’ с неопределенной

ошибкой 1. Шаблон доступа к вложенным объектам Оливера Стила

, но он испортит их экземпляр при клонировании.

jsfiddle

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

ОК,

представьте, что у вас есть этот объект ниже, и вы хотите его клонировать: Глядя на вывод

, ответ в основном зависит от того, какой ECMAscript вы используете, в

, вы можете просто использовать

сделать клон:

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.

или использование оператора распространения, подобного этому: Но если вы используете , вы можете использовать несколько методов, но

, просто убедитесь, что вы не используете для копирования большой кусок данных, но это может во многих случаях удобно использовать одну строку: что-то вроде этого:

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)

Как указывают @squint и @mekdev, вы получаете лучшая производительность, сначала создав функцию вне цикла, а затем связав результаты внутри цикла. Конечно, функции не принадлежат JSON, поэтому это работает только для объектов без методов-членов. список Python (анализируется из текстовой строки 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']}
]

grep jQuery , позволяющую фильтровать массив:

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>

My stringjson исходит из файла PHP, но все же, я указываю здесь, в var. Когда я непосредственно перенесу свой json в obj, это ничего не покажет, поэтому я помещаю свой json-файл как

var obj=JSON.parse(stringjson);, после чего я получаю message obj и показываю в окне предупреждения, затем я получаю data который является массивом json и хранится в одной переменной ArrObj, затем я читаю первый объект этого массива со значением ключа, подобным этому ArrObj[0].id

     var stringjson={
        "success": true,
        "message": "working",
        "data": [{
                  "id": 1,
                  "name": "foo"
         }]
      };

                var obj=JSON.parse(stringjson);
                var key = "message";
                alert(obj[key]);
                var keyobj = "data";
                var ArrObj =obj[keyobj];

                alert(ArrObj[0].id);

Использование lodash было бы хорошим решением

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