iterate through a map in javascript

后端 未结 5 1586
温柔的废话
温柔的废话 2021-02-01 13:13

I have a structure like this:

var myMap = {
    partnr1: [\'modelA\', \'modelB\', \'modelC\'],
    partnr2: [\'modelA\', \'modelB\', \'modelC\']
};
相关标签:
5条回答
  • 2021-02-01 13:43

    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)
    })
    
    0 讨论(0)
  • 2021-02-01 13:47

    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.

    0 讨论(0)
  • 2021-02-01 13:53

    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);
      });
    });
    
    0 讨论(0)
  • 2021-02-01 13:54

    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.

    0 讨论(0)
  • 2021-02-01 13:58

    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);
    }
    
    0 讨论(0)
提交回复
热议问题