如何迭代对象的属性值对?

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

我有这样的结构:

var myMap = {
    partnr1: ['modelA', 'modelB', 'modelC'],
    partnr2: ['modelA', 'modelB', 'modelC']
};

我将迭代每个元素(partnr)及其关联项(模型)。

我正在尝试两次

$each()
迭代以实现此目的,但没有任何反应:

$.each(myMap, function (i, val) {
    $.each(i, function (innerKey, innerValue) {

        setTimeout(function () {
            $('#variant').fadeOut("slow", function () {
                $(this).text(innerKey + "-" + innerValue).fadeIn("slow");

            });

        }, i * 6000);

    });
});

我试图实现的淡入淡出效果在使用单值数组(

Object
)时工作正常,但当我需要像这里一样为每个键拥有多个值时则不然。

如何成功完成本次迭代?在这种情况下,除了使用

Object
之外,还有其他方法会更好吗?

javascript dictionary
8个回答
175
投票

您 2019 年问题的答案:

这取决于您使用的 ECMAScript 版本。

ES6 之前:

使用以下任何答案,例如:

for (var m in myMap){
    for (var i=0;i<myMap[m].length;i++){
    ... do something with myMap[m][i] ...
    }
} 

对于 ES6(ES 2015):

您应该使用

Map
对象,它具有
entries()
功能:

var myMap = new Map();
myMap.set("0", "foo");
myMap.set(1, "bar");
myMap.set({}, "baz");

for (const [key, value] of myMap.entries()) {
  console.log(key, value);
}

// Or functional
myMap.forEach((value, key) => {
    console.log(value, key)
})

对于 ES8(ES 2017):

Object.entries()
介绍:

const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
  console.log(key, value);
}

48
投票

我会使用标准的 javascript:

for (var m in myMap){
    for (var i=0;i<myMap[m].length;i++){
    ... do something with myMap[m][i] ...
    }
} 

注意处理对象和数组的不同方式。


42
投票

ES6+ 的函数式方法

如果你想采用更实用的方法来迭代

Map
对象,你可以这样做

const myMap = new Map() 
myMap.forEach((value, key) => {
    console.log(value, key)
})

9
投票

嗯,看来这个旧的 JQuery 线程已被 ES6 Map 用户采用。

如果这就是您正在寻找的,我可以建议使用

Array.from()
函数将
Map
转换为
Array
。这使您可以轻松地进行链式变换,例如
filter()
map()
等。

const map = new Map([
  ['key one', 'value one'],
  ['key two', 'value two'],
]);

// Loop through key-value-pairs
Array.from(map.entries()).map(([key, val]) => console.log(key, val));

// Loop through map keys
Array.from(map.keys()).map(key => console.log(key));

// Loop through values
Array.from(map.values()).map(value => console.log(value));

5
投票

$.each()
的回调按顺序传递属性名称和值。因此,您尝试在对
$.each()
的内部调用中迭代属性名称。我想你想要:

$.each(myMap, function (i, val) {
  $.each(val, function(innerKey, innerValue) {
    // ...
  });
});

在内部循环中,给定一个像地图这样的对象,值是数组。没关系,但请注意“innerKey”值都是数字。

编辑 — 现在一旦解决了,下一个问题就是:

    setTimeout(function () {

      // ...

    }, i * 6000);

第一次循环时,“i”将是字符串“partnr1”。因此,该乘法尝试将得到

NaN
。您可以保留一个外部计数器来跟踪外部地图的属性计数:

var pcount = 1;
$.each(myMap, function(i, val) {
  $.each(val, function(innerKey, innerValue) {
    setTimeout(function() {
      // ...
    }, pcount++ * 6000);
  });
});

1
投票

不要使用迭代器来执行此操作。通过增加回调中的计数器并递归调用下一项的操作来维护您自己的循环。

$.each(myMap, function(_, arr) {
    processArray(arr, 0);
});

function processArray(arr, i) {
    if (i >= arr.length) return;

    setTimeout(function () {
        $('#variant').fadeOut("slow", function () {
            $(this).text(i + "-" + arr[i]).fadeIn("slow");

            // Handle next iteration
            processArray(arr, ++i);
        });
    }, 6000);
}

虽然您的代码中有逻辑错误。您(大致)同时将同一个容器设置为多个不同的值。也许您的意思是每个人都更新自己的容器。


0
投票

我们可以使用 ES6 版本中地图上可用的 forEach 方法。

var myMap =new Map([
    ["partnr1", ['modelA', 'modelB', 'modelC']],
    ["partnr2", ['modelA', 'modelB', 'modelC']]
]);

myMap.forEach(function(values,key){
  
  console.log(key);
  
  /*****Do something with the models***********/
  
  for(const [index,value] of values.entries()){
      console.log(`   ${key}[${index}] : ${value}`);
  }
  });


0
投票

这可以使用 javascript

Map
对象轻松实现。您只需迭代
Map
,使用您正在迭代的映射作为参数包含在每个迭代调用中这一事实。请注意
map
函数中的
forEach
参数。这与您正在迭代的
Map
对象相同。


// Define the map
const myMap = new Map([
    ["key1", "value 1"],
    ["key2": "value 2"],
    ["key3": "value 3"]
])

// Iterate over the map, updating each value
myMap.forEach((value,key,map) => {
   map.set(key, value + "A")
})

/*
Result: myMap now looks like this:
[ 
    ["key1", "value 1A"],
    ["key2": "value 2A"],
    ["key3": "value 3A"]
]
/*
© www.soinside.com 2019 - 2024. All rights reserved.