web-dev-qa-db-ja.com

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の名前/番号をオンザフライで生成しようとしましたが、オブジェクト名の文字列を使用してオブジェクトにアクセスできないため、ここからどこに進むべきかわかりません。

51
Eric

これには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);
115
Roel van Uden

私の問題は、実際のロジックの問題ではなく、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を取得する方法は、すべてのブラウザーでサポートされているわけではありません。私のプロジェクトでは、実際には問題ではありませんが、これに似たものを使用することを選択した場合は注意してください。

10
Eric

これが私の再帰的なアプローチです。

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

オブジェクト全体のkey [value]を出力する@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

0
JMerinoH