遍历对象

问题描述 投票:0回答:7

我很难找到一种方法以我想要的方式迭代这个对象。我在这里只使用 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的名称/编号,但我无法使用对象名称的字符串来访问该对象,所以我不确定从这里该去哪里。

javascript object
7个回答
170
投票

为此,您使用

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

14
投票

我的问题实际上是 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);
    }

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


8
投票

这是我的递归方法:

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

0
投票

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


0
投票

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


0
投票

更简单的方法是(刚刚在 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);

0
投票
let myObj = {
  "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."
      }
  }
};

将对象分配给变量

myObj

让我们尝试一些代码片段以更好地理解。

Code-1: console.log(myObj.dialog)
Output :
{
  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.'
  }
}
Code : 2 console.log(myObj.dialog.dialog_trunk_1)
Output : 
{ message: 'This is just a JSON Test' }
Code : 3 console.log(myObj.dialog.dialog_trunk_1.message)
Output : 
This is just a JSON Test
Code : 4 console.log(myObj.dialog['dialog_trunk_1']);
Output : 
{ message: 'This is just a JSON Test' }
Code : 5 

for(let i in myObj.dialog){
  console.log(i)
}

Output :

dialog_trunk_1
dialog_trunk_2
dialog_trunk_3

最终代码:

Code : 6

for(let i in myObj.dialog){
  console.log(myObj.dialog[i].message)
}

// Using for in loop we get access of the keys of the object.
// Now as we are getting string as the keys. We will be using the square bracket to access them dynamically.
// Read more about dot and square annotation.

Output :

This is just a JSON Test
and a test of the second 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.
© www.soinside.com 2019 - 2024. All rights reserved.