Я хотел бы просмотреть дерево объектов JSON, но не могу найти для этого никакой библиотеки. Это не кажется сложным, но похоже на изобретение колеса.
В XML так много учебных пособий, показывающих, как обходить дерево XML с помощью DOM :(
javascript
json
Пэтси Исса
источник
источник
Ответы:
Если вы думаете, что jQuery является излишним для такой примитивной задачи, вы можете сделать что-то вроде этого:
источник
this
значение в целевой функции, тогдаo
как первым параметром этой функции должен быть. Установка его вthis
(что было быtraverse
функцией) хоть и немного странная, ноprocess
вthis
любом случае она не использует ссылку. С таким же успехом это могло бы быть нулевым./*jshint validthis: true */
выше,func.apply(this,[i,o[i]]);
чтобы избежать ошибки,W040: Possible strict violation.
вызванной использованиемthis
traverse
функцию, которая отслеживает глубину. При вызове рекурсивно добавьте 1 к текущему уровню.Объект JSON - это просто объект Javascript. Вот что на самом деле означает JSON: JavaScript Object Notation. Таким образом, вы будете проходить через объект JSON, но в целом вы будете выбирать «обходить» объект Javascript.
В ES2017 вы бы сделали:
Вы всегда можете написать функцию, чтобы рекурсивно спускаться в объект:
Это должно быть хорошей отправной точкой. Я настоятельно рекомендую использовать современные методы javascript для таких вещей, поскольку они значительно облегчают написание такого кода.
источник
function traverse(jsonObj) { if(jsonObj && typeof jsonObj == "object" ) { ...
источник
much better
?!!o[i] && typeof o[i] == 'object'
Существует новая библиотека для обхода данных JSON с помощью JavaScript, которая поддерживает множество различных вариантов использования.
https://npmjs.org/package/traverse
https://github.com/substack/js-traverse
Он работает со всеми видами объектов JavaScript. Он даже обнаруживает циклы.
Он также предоставляет путь к каждому узлу.
источник
Зависит от того, что вы хотите сделать. Вот пример обхода дерева объектов JavaScript, печати ключей и значений по ходу дела:
источник
Если вы просматриваете фактическую строку JSON, тогда вы можете использовать функцию reviver.
При прохождении объекта:
источник
EDIT : Все ниже примеры в этом ответе были отредактированы , чтобы включить новый переменный путь из выданного итератора , как на @ supersan по просьбе . Переменная path - это массив строк, где каждая строка в массиве представляет каждый ключ, к которому был получен доступ для получения итогового итерированного значения из исходного исходного объекта. Переменная пути может быть передана в функцию / метод get lodash . Или вы можете написать свою собственную версию get lodash, которая обрабатывает только массивы следующим образом:
РЕДАКТИРОВАТЬ : Этот отредактированный ответ решает бесконечные обходы цикла.
Остановка досадных обходов бесконечных объектов
Этот отредактированный ответ все еще предоставляет одно из дополнительных преимуществ моего исходного ответа, который позволяет вам использовать предоставленную функцию генератора для использования более чистого и простого итерируемого интерфейса (подумайте, используя
for of
циклы,for(var a of b)
гдеb
итеративныйa
элемент является элементом итерируемого элемента). ). Используя функцию генератора и будучи более простым API, он также помогает с повторным использованием кода, делая его таким образом, чтобы вам не приходилось повторять логику итерации везде, где вы хотите глубоко перебрать свойства объекта, и это также дает возможностьbreak
выйти из цикл, если вы хотите остановить итерацию раньше.Одна вещь, которую я заметил, что она не была рассмотрена и которой нет в моем первоначальном ответе, это то, что вы должны быть осторожны при обходе произвольных (то есть любого «случайного» набора) объектов, потому что объекты JavaScript могут быть самоссылочными. Это создает возможность иметь бесконечные циклические обходы. Однако немодифицированные данные JSON не могут быть самореферентными, поэтому, если вы используете это конкретное подмножество объектов JS, вам не нужно беспокоиться о бесконечном цикле обходов, и вы можете ссылаться на мой оригинальный ответ или другие ответы. Вот пример бесконечного обхода (обратите внимание, что это не исполняемый фрагмент кода, потому что в противном случае он может вызвать сбой на вкладке браузера).
Также в объекте генератора в моем отредактированном примере я решил использовать
Object.keys
вместоfor in
которого итерации только не прототипных ключей объекта. Вы можете поменять это самостоятельно, если хотите включить ключи прототипа. Смотрите мой оригинальный раздел ответа ниже для обеих реализаций сObject.keys
иfor in
.Хуже - это приведет к бесконечному циклу на объектах со ссылками:
Чтобы уберечься от этого, вы можете добавить набор в замыкание, чтобы при первом вызове функции он начал формировать память об объектах, которые он видел, и не продолжал итерацию, когда натолкнулся на уже увиденный объект. Приведенный ниже фрагмент кода делает это и, таким образом, обрабатывает бесконечные циклы.
Лучше - это не будет бесконечным циклом на объектах с ссылками:
Оригинальный ответ
Для более нового способа сделать это, если вы не против отказаться от IE и в основном поддерживать более современные браузеры (проверьте совместимость с таблицей es6 в kangax ). Вы можете использовать генераторы es2015 для этого. Я обновил ответ @ TheHippo соответственно. Конечно, если вы действительно нуждаетесь в поддержке IE, вы можете использовать babel JavaScript-транспортер.
Если вы хотите только собственные перечислимые свойства ( в основном свойства без цепи прототипов) , вы можете изменить его итерация , используя
Object.keys
и вfor...of
цикле вместо:источник
Я хотел использовать идеальное решение @TheHippo в анонимной функции, без использования функций процесса и триггера. Следующее работает для меня, разделяя для начинающих программистов, как я.
источник
Большинство движков Javascript не оптимизируют хвостовую рекурсию (это может не быть проблемой, если ваш JSON не глубоко вложен), но я обычно ошибаюсь из-за осторожности и вместо этого выполняю итерацию, например
источник
Мой сценарий:
Введите JSON:
Вызов функции:
Выход согласно моей потребности:
источник
источник
Лучшее решение для меня было следующее:
просто и без использования каких-либо рамок
источник
Вы можете получить все ключи / значения и сохранить иерархию с этим
Это изменение на ( https://stackoverflow.com/a/25063574/1484447 )
источник
источник
Я создал библиотеку для обхода и редактирования глубоко вложенных объектов JS. Проверьте API здесь: https://github.com/dominik791
Вы также можете поиграть с библиотекой в интерактивном режиме с помощью демонстрационного приложения: https://dominik791.github.io/obj-traverse-demo/
Примеры использования: у вас всегда должен быть корневой объект, который является первым параметром каждого метода:
Второй параметр - это всегда имя свойства, которое содержит вложенные объекты. В приведенном выше случае это будет
'children'
.Третий параметр - это объект, который вы используете для поиска объекта / объектов, которые вы хотите найти / изменить / удалить. Например, если вы ищете объект с идентификатором, равным 1, то вы передадите
{ id: 1}
в качестве третьего параметра.И вы можете:
findFirst(rootObj, 'children', { id: 1 })
найти первый объект сid === 1
findAll(rootObj, 'children', { id: 1 })
найти все объекты сid === 1
findAndDeleteFirst(rootObj, 'children', { id: 1 })
удалить первый соответствующий объектfindAndDeleteAll(rootObj, 'children', { id: 1 })
удалить все подходящие объектыreplacementObj
используется в качестве последнего параметра в двух последних методах:findAndModifyFirst(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
изменить первый найденный объектid === 1
на{ id: 2, name: 'newObj'}
findAndModifyAll(rootObj, 'children', { id: 1 }, { id: 2, name: 'newObj'})
изменить все объекты сid === 1
к{ id: 2, name: 'newObj'}
источник