簡體   English   中英

如何迭代 JavaScript object?

[英]How to iterate over a JavaScript object?

我在 JavaScript 中有一個 object:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

我想使用for循環來獲取它的屬性。 而且我想部分迭代它(不是一次所有的 object 屬性)。

使用一個簡單的數組,我可以使用標准for循環來做到這一點:

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

但是如何處理對象呢?

要迭代Arrays、Strings 或 Objects的鍵,請使用for .. in

for (let key in yourobject) {
  console.log(key, yourobject[key]);
}

使用 ES6,如果您同時需要鍵和值,請執行

for (let [key, value] of Object.entries(yourobject)) {
    console.log(key, value);
}

要避免記錄繼承的屬性,請檢查hasOwnProperty

for (let key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}

如果您使用的是簡單對象(例如您自己使用{}制作的對象),則在迭代鍵時無需檢查hasOwnProperty

這個 MDN 文檔更一般地解釋了如何處理對象及其屬性。

如果你想“分塊”做,最好是提取數組中的鍵。 由於無法保證訂單,因此這是正確的方法。 在現代瀏覽器中,您可以使用

let keys = Object.keys(yourobject);

為了更加兼容,你最好這樣做:

 let keys = [];
 for (let key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

然后你可以通過索引迭代你的屬性: yourobject[keys[i]]

for (let i=300; i < keys.length && i < 600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

這是現代瀏覽器的另一種迭代解決方案:

Object.keys(obj)
  .filter((k, i) => i >= 100 && i < 300)
  .forEach(k => console.log(obj[k]));

或者沒有過濾功能:

Object.keys(obj).forEach((k, i) => {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

但是,您必須考慮 JavaScript 對象中的屬性沒有排序,即沒有順序。

使用Object.entries你可以做這樣的事情。

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

Object.entries() 方法返回給定對象自己的可枚舉屬性 [key, value] 的數組

因此,您可以遍歷 Object 並為每個對象擁有keyvalue ,並獲得類似的東西。

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

或者像這樣

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

如需參考,請查看對象條目的 MDN 文檔

借助新的 ES6/ES2015 特性,您不必再使用對象來迭代哈希。 您可以使用Map Javascript Maps 將鍵保持在插入順序中,這意味着您可以迭代它們而無需檢查 hasOwnProperty,這一直是一個 hack。

遍歷地圖:

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

或使用 forEach:

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

如果您在迭代時需要鍵和值,可以使用for...of循環和Object.entries

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

唯一可靠的方法是將您的對象數據保存到 2 個數組中,一個鍵和一個用於數據:

var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

然后,您可以像往常一樣遍歷數組:

for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

我沒有使用Object.keys(obj) ,因為那是 IE 9+。

Object.keys(Array).forEach(key => {

 console.log('key',key)

})

如果您有一個簡單的對象,則可以使用以下代碼對其進行迭代:

 let myObj = { abc: '...', bca: '...', zzz: '...', xxx: '...', ccc: '...', // ... }; let objKeys = Object.keys(myObj); //Now we can use objKeys to iterate over myObj for (item of objKeys) { //this will print out the keys console.log('key:', item); //this will print out the values console.log('value:', myObj[item]); }

如果您有一個嵌套對象,您可以使用以下代碼對其進行迭代:

 let b = { one: { a: 1, b: 2, c: 3 }, two: { a: 4, b: 5, c: 6 }, three: { a: 7, b: 8, c: 9 } }; let myKeys = Object.keys(b); for (item of myKeys) { //print the key console.log('Key', item) //print the value (which will be another object) console.log('Value', b[item]) //print the nested value console.log('Nested value', b[item]['a']) }

如果您有對象數組,則可以使用以下代碼對其進行迭代:

 let c = [ { a: 1, b: 2 }, { a: 3, b: 4 } ]; for(item of c){ //print the whole object individually console.log('object', item); //print the value inside the object console.log('value', item['a']); }

const o = {
  name: "Max",
  location: "London"
};

for (const [key, value] of Object.entries(o)) {
  console.log(`${key}: ${value}`);
}

在線嘗試

如果你想一次迭代整個對象,你可以使用for in循環:

for (var i in obj) {
  ...
}

但是,如果您想將對象分成幾部分,實際上是做不到的。 無法保證對象中的屬性按任何指定的順序排列。 因此,我可以想到兩種解決方案。

首先是“刪除”已經讀取的屬性:

var i = 0;
for (var key in obj) {
    console.log(obj[key]);
    delete obj[key];
    if ( ++i > 300) break;
}

我能想到的另一個解決方案是使用 Array of Arrays 而不是對象:

var obj = [['key1', 'value1'], ['key2', 'value2']];

然后,標准for循環將起作用。

我終於想出了一個方便的實用函數,它有一個統一的接口來迭代對象、字符串、數組、TypedArrays、Maps、Sets(任何 Iterables)。

const iterate = require('@a-z/iterate-it');
const obj = { a: 1, b: 2, c: 3 };

iterate(obj, (value, key) => console.log(key, value)); 
// a 1
// b 2
// c 3

https://github.com/alrik/iterate-javascript

對於對象迭代,我們通常使用for..in循環。 該結構將遍歷所有可枚舉的屬性,包括通過原型繼承繼承的屬性。 例如:

 let obj = { prop1: '1', prop2: '2' } for(let el in obj) { console.log(el); console.log(obj[el]); }

但是, for..in將遍歷所有可枚舉元素,這將無法讓我們將迭代分成塊。 為此,我們可以使用內置的Object.keys()函數來檢索數組中對象的所有鍵。 然后,我們可以將迭代拆分為多個 for 循環並使用鍵數組訪問屬性。 例如:

 let obj = { prop1: '1', prop2: '2', prop3: '3', prop4: '4', }; const keys = Object.keys(obj); console.log(keys); for (let i = 0; i < 2; i++) { console.log(obj[keys[i]]); } for (let i = 2; i < 4; i++) { console.log(obj[keys[i]]); }

是的。 您可以使用 for 循環遍歷對象。 這是一個例子

 var myObj = { abc: 'ABC', bca: 'BCA', zzz: 'ZZZ', xxx: 'XXX', ccc: 'CCC', } var k = Object.keys (myObj); for (var i = 0; i < k.length; i++) { console.log (k[i] + ": " + myObj[k[i]]); }

注意:上面提到的例子只適用於 IE9+。 請參閱此處的 Objec.keys 瀏覽器支持。

<script type="text/javascript">
// method 1
var images = {};
images['name'] = {};
images['family'] = {};
images[1] = {};
images['name'][5] = "Mehdi";
images['family'][8] = "Mohammadpour";
images['family']['ok'] = 123456;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][22] = 2602;
images[1][23] = 2602;

for (const [key1, value1] of Object.entries(images)){
    for (const [key2, value2] of Object.entries(value1)){
        console.log(`${key1} => ${key2}: ${value2}`);
    }
}


console.log("=============================");

// method 2
var arr = [];
for(var x = 0; x < 5; x++){
     arr[x] = [];    
     for(var y = 0; y < 5; y++){ 
         arr[x][y] = x*y;    
     }    
 }

for(var i = 0; i < arr.length; i++) {
    var cube = arr[i];
    for(var j = 0; j < cube.length; j++) {
        console.log("cube[" + i + "][" + j + "] = " + cube[j]);
    }
}

</script>

在參數中定義對象並避免選擇器和下標

有許多語法選擇,但是這個在閉包的參數中預先定義了對象,這消除了迭代器中對選擇器或下標的需要。 k是鍵, v是值, i是索引。

const obj = {
    kiwi: true,
    mango: false,
    pineapple: 500
};

Object.entries(obj).forEach(([k, v], i) => {
    console.log(k, v, i);
});

// kiwi true 0
// mango false 1
// pineapple 500 2
var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

您可以嘗試使用lodash - 一個現代 JavaScript 實用程序庫,提供模塊化、性能和附加js 以快速對象迭代:-

 var  users  =   { 'fred':     { 'user':   'fred',    'age':  40 }, 'pebbles':  { 'user':   'pebbles', 'age':  1 } }; _.mapValues(users,  function(o)  { return  o.age; }); // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) // The `_.property` iteratee shorthand. console.log(_.mapValues(users,  'age')); // returns age property & value console.log(_.mapValues(users,  'user')); // returns user property & value console.log(_.mapValues(users)); // returns all objects // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
 <script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>

真正的 PITA,這不是標准 Javascript 的一部分。

/**
 * Iterates the keys and values of an object.  Object.keys is used to extract the keys.
 * @param object The object to iterate
 * @param fn (value,key)=>{}
 */
function objectForEach(object, fn) {
    Object.keys(object).forEach(key => {
        fn(object[key],key, object)
    })
}

注意:我將回調參數切換為 (value,key) 並添加了第三個對象以使 API 與其他 API 保持一致。

像這樣使用它

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
    // do something
});

使用ES6,您需要同時使用鍵和值,請使用這些方法。

for (let [key, value] of Object.entries(your_object)) {
     console.log(key, value);
}

這是一個手工制作的解決方案:

function iterationForObject() {
    let base = 0,
        Keys= Object.keys(this);
    return {
        next: () => {
            return {
                value: {
                    "key": Keys[base],
                    "value": this[Keys[base]]
                },
                done: !(base++ < Keys.length)
            };
        }
    };
}
Object.prototype[Symbol.iterator] = iterationForObject;

然后你可以循環任何對象:

for ( let keyAndValuePair of (Object Here) ) {
    console.log(`${keyAndValuePair.key} => ${keyAndValuePair.value}`);
}

我在JavaScript中有一個對象:

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

我想使用一個for循環來獲取它的屬性。 而且我想對其進行部分迭代(不是一次遍歷所有對象屬性)。

通過一個簡單的數組,我可以使用標准的for循環來做到這一點:

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

但是如何處理對象呢?

暫無
暫無

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

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