Итерация через json-объект javascript
Мне очень сложно найти способ итерации через этот объект JSON так, как хотелось бы. Я использую только Javascript здесь.
Во-первых, здесь объект
{
"dialog":
{
"dialog_trunk_1":{
"message": "This is just a JSON Test"
},
"dialog_trunk_2":{
"message": "and a test of the second message"
},
"dialog_trunk_3":
{
"message": "This is a test of a bit longer text. Hopefully this will at the very least create 3 lines and trigger us to go on to another box. So we can test multi-box functionality, too."
}
}
}
Прямо сейчас, я просто пытаюсь выполнить основные способы доступа к каждому dialog_trunk на этом объекте. Я в идеале хочу прокрутить объект и для каждой соединительной линии, отобразить его message
.
Я пробовал использовать цикл for для генерации имени/числа dialog_trunk на лету, но я не могу получить доступ к объекту, используя строку для имени объекта, поэтому я не уверен, куда идти отсюда.
Ответы
Ответ 1
Для этого используется цикл for..in
. Не забудьте проверить, принадлежит ли объект свойствам или все унаследованные свойства. Пример такой:
var obj = {a: 1, b: 2};
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
console.log(val);
}
}
Или, если вам нужна рекурсия, чтобы просмотреть все свойства:
var obj = {a: 1, b: 2, c: {a: 1, b: 2}};
function walk(obj) {
for (var key in obj) {
if (obj.hasOwnProperty(key)) {
var val = obj[key];
console.log(val);
walk(val);
}
}
}
walk(obj);
Ответ 2
Моя проблема была на самом деле проблемой плохого планирования с объектом JSON, а не с реальной логической проблемой. То, что я закончил, заключалось в организации объекта следующим образом, по предложению пользователя2736012.
{
"dialog":
{
"trunks":[
{
"trunk_id" : "1",
"message": "This is just a JSON Test"
},
{
"trunk_id" : "2",
"message": "This is a test of a bit longer text. Hopefully this will at the very least create 3 lines and trigger us to go on to another box. So we can test multi-box functionality, too."
}
]
}
}
В этот момент я смог сделать довольно простой цикл, основанный на общем количестве объектов.
var totalMessages = Object.keys(messages.dialog.trunks).length;
for ( var i = 0; i < totalMessages; i++)
{
console.log("ID: " + messages.dialog.trunks[i].trunk_id + " Message " + messages.dialog.trunks[i].message);
}
Мой метод получения totalMessages не поддерживается во всех браузерах. Для моего проекта это на самом деле не имеет значения, но будьте осторожны, если вы решите использовать что-то похожее на это.
Ответ 3
Вот мой рекурсивный подход:
function visit(object) {
if (isIterable(object)) {
forEachIn(object, function (accessor, child) {
visit(child);
});
}
else {
var value = object;
console.log(value);
}
}
function forEachIn(iterable, functionRef) {
for (var accessor in iterable) {
functionRef(accessor, iterable[accessor]);
}
}
function isIterable(element) {
return isArray(element) || isObject(element);
}
function isArray(element) {
return element.constructor == Array;
}
function isObject(element) {
return element.constructor == Object;
}
Ответ 4
Улучшенная версия рекурсивного подхода, предложенная @schirrmacher для печати ключа [значения] для всего объекта:
var jDepthLvl = 0;
function visit(object, objectAccessor=null) {
jDepthLvl++;
if (isIterable(object)) {
if(objectAccessor === null) {
console.log("%c ⇓ ⇓ printing object $OBJECT_OR_ARRAY$ -- START ⇓ ⇓", "background:yellow");
} else
console.log("%c"+spacesDepth(jDepthLvl)+objectAccessor+"%c:","color:purple;font-weight:bold", "color:black");
forEachIn(object, function (accessor, child) {
visit(child, accessor);
});
} else {
var value = object;
console.log("%c"
+ spacesDepth(jDepthLvl)
+ objectAccessor + "[%c" + value + "%c] "
,"color:blue","color:red","color:blue");
}
if(objectAccessor === null) {
console.log("%c ⇑ ⇑ printing object $OBJECT_OR_ARRAY$ -- END ⇑ ⇑", "background:yellow");
}
jDepthLvl--;
}
function spacesDepth(jDepthLvl) {
let jSpc="";
for (let jIter=0; jIter<jDepthLvl-1; jIter++) {
jSpc+="\u0020\u0020"
}
return jSpc;
}
function forEachIn(iterable, functionRef) {
for (var accessor in iterable) {
functionRef(accessor, iterable[accessor]);
}
}
function isIterable(element) {
return isArray(element) || isObject(element);
}
function isArray(element) {
return element.constructor == Array;
}
function isObject(element) {
return element.constructor == Object;
}
visit($OBJECT_OR_ARRAY$);
![Console Output using JSON from @eric]()