循环遍历对象

我真的很难找到一种方法来以我喜欢的方式遍历这个对象。我在这里只使用 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."
}
}
}

现在,我只是尝试通过一些基本的方法来访问这个对象上的每个对话框。在理想情况下,我希望循环遍历该对象,并为每个主干显示它的 message值。

我曾经尝试使用 for 循环动态地生成氮对话框主干的名称/编号,但是我不能使用对象名称的字符串访问该对象,所以我不确定从这里开始要做什么。

232606 次浏览

对此使用 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);

我的问题实际上是用 JSON 对象进行错误规划的问题,而不是实际的逻辑问题。我最后所做的就是按照 user2736012的建议来组织对象。

{
"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."
}
]
}
}

在这一点上,我能够根据对象的总数来做一个相当简单的 for 循环。

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

不过,并非所有浏览器都支持我获取 talMessages 的方法。对于我的项目,它实际上并不重要,但是如果您选择使用类似的东西,请注意这一点。

下面是我的递归方法:

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

@ schirrmacher 建议的用于为整个对象打印键[ value ]的递归方法的改进版本:

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

var res = {
"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."
}
}
}




for (var key in res) {
if (res.hasOwnProperty(key)) {
var val = res[key];
for (var key in val) {
if (val.hasOwnProperty(key)) {
var dialog = val[key];
console.log(dialog.message);
}
}
}
}

更简单的方法是(只在 W3Schools 上找到) :

let data = {.....}; // JSON Object
for(let d in data){
console.log(d); // It gives you property name
console.log(data[d]); // And this gives you its value
}

更新

在处理嵌套对象之前,这种方法可以很好地工作,因此这种方法可以工作。

const iterateJSON = (jsonObject, output = {}) => {
for (let d in jsonObject) {
if (typeof jsonObject[d] === "string") {
output[d] = jsonObject[d];
}
if (typeof jsonObject[d] === "object") {
output[d] = iterateJSON(jsonObject[d]);
}
}
return output;
}

然后像这样使用方法

let output = iterateJSON(your_json_object);