簡體   English   中英

遍歷 object

[英]iterating through object

我很難找到一種方法來以我想要的方式迭代這個 object。 我在這里只使用 Javascript。

首先,這是 object

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

現在,我只是在嘗試基本的方法來訪問這個 object 上的每個 dialog_trunk。 理想情況下,我想遍歷 object 並為每個中繼顯示它的message值。

我嘗試使用 for 循環動態生成 dialog_trunk 的名稱/編號,但我無法使用 object 名稱的字符串訪問 object,所以我不確定 Z34D1F91FB2E514B8576ZFAB1A7 的位置。

為此,您可以使用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);
    }

但是,並非所有瀏覽器都支持我獲取 totalMessages 的方法。 對於我的項目,這實際上並不重要,但是如果您選擇使用類似的東西,請注意這一點。

這是我的遞歸方法:

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 建議的遞歸方法的改進版本,用於打印整個對象的 key[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$);

使用來自@eric 的 JSON 的控制台輸出

 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
}

更新

在您處理嵌套的 object 之前,這種方法可以正常工作,因此這種方法將有效。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM