iterate through a map in javascript

JavascriptJqueryMap

Javascript Problem Overview


I have a structure like this:

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

I am going to iterate through each of the elements (partnr) with their associatives (models).

I am trying a double $each iteration in order to achieve this, but nothing happens:

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

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

            });

        }, i * 6000);

    });
});

The effect with fading in and out that I am trying to achieve is working fine when using a single value array (Object), but not when I need to have more than one value for each key like here.

Any ideas of how to accomplish this iteration succesfully and are there other ways than using a map that would be better in this case ?

Any suggestions would be of interest.

Javascript Solutions


Solution 1 - Javascript

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);
}

Solution 2 - Javascript

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.

Solution 3 - Javascript

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)
})

Solution 4 - Javascript

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);
  });
});

Solution 5 - Javascript

Well, it looks like this old JQuery thread has been coopted by ES6 Map users.

If this is what you're looking for, may I suggest using the Array.from() function which converts the Map to an Array. This allows you to easily chain transforms such as filter(), map(), etc.

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));

Solution 6 - Javascript

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.

Solution 7 - Javascript

We can use forEach Method available on maps From ES6 Version.

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}`);
  }
  });

Solution 8 - Javascript

This is easily achieved using a javascript Map object. You simply iterate over the Map, using the fact that the map you're iterating over is included as an argument in each iteration call. Notice the map argument in the forEach function. This is the same Map object you're iterating over.


// 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"]
]
/*

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser2374903View Question on Stackoverflow
Solution 1 - JavascriptDavid SchumannView Answer on Stackoverflow
Solution 2 - JavascriptAtleView Answer on Stackoverflow
Solution 3 - Javascriptjpthesolver2View Answer on Stackoverflow
Solution 4 - JavascriptPointyView Answer on Stackoverflow
Solution 5 - JavascriptStephen PaulView Answer on Stackoverflow
Solution 6 - Javascriptuser1106925View Answer on Stackoverflow
Solution 7 - JavascriptKb019View Answer on Stackoverflow
Solution 8 - JavascriptEmanuel LindströmView Answer on Stackoverflow