Ответ 1
Я бы использовал стандартный javascript:
for (var m in myMap){
for (var i=0;i<myMap[m].length;i++){
... do something with myMap[m][i] ...
}
}
Обратите внимание на различные способы обработки объектов и массивов.
У меня есть такая структура:
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), но не тогда, когда мне нужно иметь более одного значения для каждого ключа, как здесь.
Любые идеи о том, как успешно выполнить эту итерацию и есть ли другие способы, чем использовать карту, которая была бы лучше в этом случае?
Любые предложения представляли бы интерес.
Я бы использовал стандартный javascript:
for (var m in myMap){
for (var i=0;i<myMap[m].length;i++){
... do something with myMap[m][i] ...
}
}
Обратите внимание на различные способы обработки объектов и массивов.
Ответ на ваш вопрос от 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);
}
Обратный вызов $.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);
});
});
Не используйте итераторы для этого. Поддерживайте свой собственный цикл, увеличивая счетчик в обратном вызове и рекурсивный вызов операции для следующего элемента.
$.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);
}
Хотя в вашем коде есть логическая ошибка. Вы устанавливаете один и тот же контейнер в несколько раз в одно и то же время. Возможно, вы имеете в виду, чтобы каждый из них обновлял свой собственный контейнер.