配列 オブジェクトをメンバとしてプレーンJavaScriptオブジェクトをループするには?




javascript 配列 ループ (16)

別のオプション:

var testObj = {test: true, test1: false};
for(let x of Object.keys(testObj)){
    console.log(x);
}

オブジェクトである値を含むJavaScriptオブジェクト内のすべてのメンバーをどのようにループすることができますか。

たとえば、これをループするにはどうすればよいですか(それぞれの "your_name"と "your_message"にアクセスします)?

var validation_messages = {
    "key_1": {
        "your_name": "jimmy",
        "your_msg": "hello world"
    },
    "key_2": {
        "your_name": "billy",
        "your_msg": "foo equals bar"
    }
}

ECMAScript-2017は、1ヵ月前に完成したばかりで、Object.values()を導入しました。 だから今これを行うことができます:

let v;
for (v of Object.values(validation_messages))
   console.log(v.your_name);   // jimmy billy

ES7では次のことができます。

for (const [key, value] of Object.entries(obj)) {
  //
}

ECMAScript 5では、 Object.keys()Array.prototype.forEach()組み合わせることができます。

var obj = {
  first: "John",
  last: "Doe"
};

//
//	Visit non-inherited enumerable keys
//
Object.keys(obj).forEach(function(key) {

  console.log(key, obj[key]);

});


再帰を使用すると、深度のオブジェクトのプロパティを返すことができます。

function lookdeep(object){
    var collection= [], index= 0, next, item;
    for(item in object){
        if(object.hasOwnProperty(item)){
            next= object[item];
            if(typeof next== 'object' && next!= null){
                collection[index++]= item +
                ':{ '+ lookdeep(next).join(', ')+'}';
            }
            else collection[index++]= [item+':'+String(next)];
        }
    }
    return collection;
}

//example

var O={
    a:1, b:2, c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
};
var lookdeepSample= 'O={'+ lookdeep(O).join(',\n')+'}';


/*  returned value: (String)
O={
    a:1, 
    b:2, 
    c:{
        c1:3, c2:4, c3:{
            t:true, f:false
        }
    },
    d:11
}

*/

for(var key in validation_messages){
    for(var subkey in validation_messages[key]){
        //code here
        //subkey being value, key being 'yourname' / 'yourmsg'
    }
}

私は上記の投稿を私が後にしたものと全く同じにすることができませんでした。

ここで他の返事と遊んだ後、私はこれを作った。 それはハッキーですが、それは動作します!

このオブジェクトの場合:

var myObj = {
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"}
};

...このコード:

// Get every value in the object into a separate array item ...
function buildArray(p_MainObj, p_Name) {
    var variableList = [];
    var thisVar = "";
    var thisYes = false;
    for (var key in p_MainObj) {
       thisVar = p_Name + "." + key;
       thisYes = false;
       if (p_MainObj.hasOwnProperty(key)) {
          var obj = p_MainObj[key];
          for (var prop in obj) {
            var myregex = /^[0-9]*$/;
            if (myregex.exec(prop) != prop) {
                thisYes = true;
                variableList.push({item:thisVar + "." + prop,value:obj[prop]});
            }
          }
          if ( ! thisYes )
            variableList.push({item:thisVar,value:obj});
       }
    }
    return variableList;
}

// Get the object items into a simple array ...
var objectItems = buildArray(myObj, "myObj");

// Now use them / test them etc... as you need to!
for (var x=0; x < objectItems.length; ++x) {
    console.log(objectItems[x].item + " = " + objectItems[x].value);
}

...コンソールでこれを生成します:

myObj.pageURL = BLAH
myObj.emailBox.model = emailAddress
myObj.emailBox.selector = #emailAddress
myObj.passwordBox.model = password
myObj.passwordBox.selector = #password

私はそれが遅いwaaayだと知っていますが、この最適化された、改善されたバージョンのAgileJonの答えを書くのに2分かかりました:

var key, obj, prop, owns = Object.prototype.hasOwnProperty;

for (key in validation_messages ) {

    if (owns.call(validation_messages, key)) {

        obj = validation_messages[key];

        for (prop in obj ) {

            // using obj.hasOwnProperty might cause you headache if there is
            // obj.hasOwnProperty = function(){return false;}
            // but owns will always work 
            if (owns.call(obj, prop)) {
                console.log(prop, "=", obj[prop]);
            }

        }

    }

}

ES6では、次のようにオブジェクトをループすることができます:( 矢印機能を使用)

Object.keys(myObj).forEach(key => {
    console.log(key);          // the name of the current key.
    console.log(myObj[key]);   // the value of the current key.
});

jsbin

ES7では、 Object.keysではなくObject.entriesを使用して、次のようなオブジェクトをループすることができます。

Object.entries(myObj).forEach(([key, val]) => {
    console.log(key);          // the name of the current key.
    console.log(val);          // the value of the current key.
});

上記は1ライナーとしても機能します:

Object.keys(myObj).forEach(key => console.log(key, myObj[key]));

jsbin

ネストされたオブジェクトをループしたい場合は、 再帰関数(ES6)を使用できます。

const loopNestedObj = (obj) => {
  Object.keys(obj).forEach(key => {
    if (obj[key] && typeof obj[key] === 'object') loopNestedObj(obj[key]);  // recurse.
    else console.log(key, obj[key]);  // or do something with key and val.
  });
};

jsbin

上記の関数と同じですが、 Object.keys代わりにES7のObject.entries使用しObject.keys

const loopNestedObj = (obj) => {
  Object.entries(obj).forEach(([key, val]) => {
    if (val && typeof val === 'object') loopNestedObj(val);  // recurse.
    else console.log(key, val);  // or do something with key and val.
  });
};

関数型プログラミングの場合は、 Object.keys / Object.entriesを使用してオブジェクトを列挙し、値を処理してからreduce()を使用して新しいオブジェクトに変換し直すことができます。

const loopNestedObj = (obj) => 
  Object.keys(obj)
    // Use .filter(), .map(), etc. if you need.
    .reduce((newObj, key) => 
      (obj[key] && typeof obj[key] === 'object') ?
        {...newObj, [key]: loopNestedObj(obj[key])} :  // recurse.
        {...newObj, [key]: obj[key]},                  // Define value.
      {});

for(var k in validation_messages) {
    var o = validation_messages[k];
    do_something_with(o.your_name);
    do_something_else_with(o.your_msg);
}

この回答は、この記事でいくつかのパフォーマンスのフィードバックを提供したソリューションの集約です。 私は2つのユースケースがあると思うし、OPは彼がループプロセス中にそれらを使用するためにキーにアクセスする必要があるかどうかは言及しなかった。

I.キーにアクセスする必要があり、

Object.keysObject.keysアプローチ

let k;
for (k of Object.keys(obj)) {

    /*        k : key
     *   obj[k] : value
     */
}

inアプローチ

let k;
for (k in obj) {

    /*        k : key
     *   obj[k] : value
     */
}

prototypeのobjプロパティを出力できるので、慎重に使用してください

✔ES7アプローチ

for (const [key, value] of Object.entries(obj)) {

}

しかし、編集の時点では、JavaScriptはこのプロシージャを構築するために多くの変数を内部的に初期化するため、ES7メソッドはお勧めできません(証明のためのフィードバックを参照)。 あなたが最適化に値する巨大なアプリケーションを開発していない限り、それは大丈夫ですが、最適化があなたの優先事項であればそれについて考えるべきです。

II。 各値にアクセスするだけで、

Object.valuesObject.valuesアプローチ

let v;
for (v of Object.values(obj)) {

}

テストについてのより多くのフィードバック:

  • Object.keysまたはObject.valuesパフォーマンスをキャッシュすることはごくわずかです

例えば、

const keys = Object.keys(obj);
let i;
for (i of keys) {
  //
}
// same as
for (i of Object.keys(obj)) {
  //
}
  • Object.values場合、Firefoxでキャッシュされた変数を持つネイティブのforループを使用すると、 for...ofループを使用するよりも少し速いようです。 しかし、その違いはそれほど重要ではなく、Chrome for...of native forループより速く実行さfor...ofので、どの場合でもObject.valuesを処理するときに使用することをおすすめします(4回目と6回目のテスト)。

  • Firefoxではfor...inループが遅いので、繰り返し中にキーをキャッシュしたいときは、 Object.keysを使用する方がよいでしょう。 Plus Chromeは両方の構造を等速で実行しています(1回目と最後のテスト)。

テストはこちらから確認できます: https : //jsperf.com/es7-and-misc-loops


私の場合(前に基づいて)、任意の数のレベルが可能です。

var myObj = {
    rrr: undefined,
    pageURL    : "BLAH",
    emailBox   : {model:"emailAddress", selector:"#emailAddress"},
    passwordBox: {model:"password"    , selector:"#password"},
    proba: {odin:{dva:"rr",trr:"tyuuu"}, od:{ff:5,ppa:{ooo:{lll:'lll'}},tyt:'12345'}}
};


function lookdeep(obj,p_Name,gg){
    var A=[], tem, wrem=[], dd=gg?wrem:A;
    for(var p in obj){
        var y1=gg?'':p_Name, y1=y1 + '.' + p;
        if(obj.hasOwnProperty(p)){
           var tem=obj[p];
           if(tem && typeof tem=='object'){
               a1=arguments.callee(tem,p_Name,true);
               if(a1 && typeof a1=='object'){for(i in a1){dd.push(y1 + a1[i])};}
            }
            else{
               dd.push(y1 + ':' + String(tem));
            }
        }
    };
    return dd
};


var s=lookdeep(myObj,'myObj',false);
for (var x=0; x < s.length; ++x) {
console.log(s[x]+'\n');}

結果:

["myObj.rrr:undefined",
"myObj.pageURL:BLAH",
"myObj.emailBox.model:emailAddress",
"myObj.emailBox.selector:#emailAddress",
"myObj.passwordBox.model:password",
"myObj.passwordBox.selector:#password",
"myObj.proba.odin.dva:rr",
"myObj.proba.odin.trr:tyuuu",
"myObj.proba.od.ff:5",
"myObj.proba.od.ppa.ooo.lll:lll",
"myObj.proba.od.tyt:12345"]

jQueryがこれを$.each()うまく$.each()ことを指摘する価値はあると思います。

参照: https://api.jquery.com/each/ : https://api.jquery.com/each/

例えば:

$('.foo').each(function() {
    console.log($(this));
});

$(this)はオブジェクト内の単一項目です。 jQueryのセレクタエンジンを使用したくない場合は、 $('.foo')を変数にスワップします。


pは値です

for (var key in p) {
  alert(key + ' => ' + p[key]);
}

または

Object.keys(p).forEach(key => { console.log(key, p[key]) })

私のために働く解決策は以下の通りです

_private.convertParams=function(params){
    var params= [];
    Object.keys(values).forEach(function(key) {
        params.push({"id":key,"option":"Igual","value":params[key].id})
    });
    return params;
}

この問題

for (var key in validation_messages) {
   var obj = validation_messages[key];
   for (var prop in obj) {
      alert(prop + " = " + obj[prop]);
   }
}

プリミティブオブジェクトのプロトタイプをループするということです。

これであなたはそれを避けます:

for (var key in validation_messages) {
   if (validation_messages.hasOwnProperty(key)) {
      var obj = validation_messages[key];
      for (var prop in obj) {
         if (obj.hasOwnProperty(prop)) {
            alert(prop + " = " + obj[prop]);
         }
      }
   }
}






javascript