I have a structure like this:
var myMap = {
partnr1: [\'modelA\', \'modelB\', \'modelC\'],
partnr2: [\'modelA\', \'modelB\', \'modelC\']
};
Functional Approach for ES6+
If you want to take a more functional approach to iterating over the Map
object, you can do something like this
const myMap = new Map()
myMap.forEach((value, key) => {
console.log(value, key)
})
I'd use standard javascript:
for (var m in myMap){
for (var i=0;i<myMap[m].length;i++){
... do something with myMap[m][i] ...
}
}
Note the different ways of treating objects and arrays.
The callback to $.each()
is passed the property name and the value, in that order. You're therefore trying to iterate over the property names in the inner call to $.each()
. I think you want:
$.each(myMap, function (i, val) {
$.each(val, function(innerKey, innerValue) {
// ...
});
});
In the inner loop, given an object like your map, the values are arrays. That's OK, but note that the "innerKey" values will all be numbers.
edit — Now once that's straightened out, here's the next problem:
setTimeout(function () {
// ...
}, i * 6000);
The first time through that loop, "i" will be the string "partnr1". Thus, that multiplication attempt will result in a NaN
. You can keep an external counter to keep track of the property count of the outer map:
var pcount = 1;
$.each(myMap, function(i, val) {
$.each(val, function(innerKey, innerValue) {
setTimeout(function() {
// ...
}, pcount++ * 6000);
});
});
Don't use iterators to do this. Maintain your own loop by incrementing a counter in the callback, and recursively calling the operation on the next item.
$.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);
}
Though there's a logic error in your code. You're setting the same container to more than one different value at (roughly) the same time. Perhaps you mean for each one to update its own container.
An answer to your Question from 2019:
It depends on what version of ECMAScript you use.
Pre ES6:
Use any of the answers below, e.g.:
for (var m in myMap){
for (var i=0;i<myMap[m].length;i++){
... do something with myMap[m][i] ...
}
}
For ES6 (ES 2015):
You should use a Map
object, which has the entries()
function:
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);
}
For ES8 (ES 2017):
Object.entries() was introduced:
const object = {'a': 1, 'b': 2, 'c' : 3};
for (const [key, value] of Object.entries(object)) {
console.log(key, value);
}