Итерация через карту в javascript - программирование

Итерация через карту в javascript

У меня есть такая структура:

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

Я собираюсь перебирать каждый из элементов (partnr) со своими ассоциациями (моделями).

Я пытаюсь выполнить двойную $каждую итерацию для достижения этого, но ничего не происходит:

$.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), но не тогда, когда мне нужно иметь более одного значения для каждого ключа, как здесь.

Любые идеи о том, как успешно выполнить эту итерацию и есть ли другие способы, чем использовать карту, которая была бы лучше в этом случае?

Любые предложения представляли бы интерес.

4b9b3361

Ответ 1

Я бы использовал стандартный javascript:

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

Обратите внимание на различные способы обработки объектов и массивов.

Ответ 2

Ответ на ваш вопрос от 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);
}

Для 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);
}

Ответ 3

Обратный вызов $.each() передается имя свойства и значение в этом порядке. Поэтому вы пытаетесь перебрать имена свойств во внутреннем вызове $.each(). Я думаю, вы хотите:

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

Во внутреннем цикле, заданном объектом, подобным вашей карте, значения представляют собой массивы. Это нормально, но обратите внимание, что значениями "innerKey" будут все числа.

edit — Теперь, когда это выпрямилось, вот следующая проблема:

    setTimeout(function () {

      // ...

    }, i * 6000);

В первый раз через этот цикл "i" будет строка "partnr1". Таким образом, попытка умножения приведет к NaN. Вы можете сохранить внешний счетчик для отслеживания счета свойств внешней карты:

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

Ответ 4

Не используйте итераторы для этого. Поддерживайте свой собственный цикл, увеличивая счетчик в обратном вызове и рекурсивный вызов операции для следующего элемента.

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

Хотя в вашем коде есть логическая ошибка. Вы устанавливаете один и тот же контейнер в несколько раз в одно и то же время. Возможно, вы имеете в виду, чтобы каждый из них обновлял свой собственный контейнер.