Javascript foreach loop для объекта ассоциативного массива
Почему мой цикл for for-each не выполняет итерацию по объекту ассоциативного массива JavaScript?
// defining an array
var array = [];
// assigning values to corresponding keys
array["Main"] = "Main page";
array["Guide"] = "Guide page";
array["Articles"] = "Articles page";
array["Forum"] = "Forum board";
// expected: loop over every item,
// yet it logs only "last" assigned value - "Forum"
for (var i = 0; i < array.length; i++) {
console.log(array[i]);
}
EDIT: jQuery each()
может быть полезным: https://api.jquery.com/jQuery.each/
Ответы
Ответ 1
Свойство .length
отслеживает свойства только с числовыми индексами (ключами). Вы используете строки для ключей.
Вы можете сделать это:
var arr_jq_TabContents = {}; // no need for an array
arr_jq_TabContents["Main"] = jq_TabContents_Main;
arr_jq_TabContents["Guide"] = jq_TabContents_Guide;
arr_jq_TabContents["Articles"] = jq_TabContents_Articles;
arr_jq_TabContents["Forum"] = jq_TabContents_Forum;
for (var key in arr_jq_TabContents) {
console.log(arr_jq_TabContents[key]);
}
Чтобы быть в безопасности, это хорошая идея в таких циклах, чтобы убедиться, что ни одно из свойств не является неожиданным результатом наследования:
for (var key in arr_jq_TabContents) {
if (arr_jq_TabContents.hasOwnProperty(key))
console.log(arr_jq_TabContents[key]);
}
edit — теперь неплохо было бы отметить, что функция Object.keys()
доступна в современных браузерах и в Node и т.д. Эта функция возвращает "собственные" ключи объекта, как массив:
Object.keys(arr_jq_TabContents).forEach(function(key, index) {
console.log(this[key]);
}, arr_jq_TabContents);
Функция обратного вызова, переданная в .forEach()
, вызывается с каждой клавишей и индексом ключа в массиве, возвращаемом Object.keys()
. Он также передал массив, через который функция выполняет итерацию, но этот массив нам не очень полезен; нам нужен оригинальный объект. К этому можно обратиться напрямую по имени, но (на мой взгляд) это немного лучше передать его явно, что делается путем передачи второго аргумента .forEach()
— исходный объект — который будет связан как this
внутри обратного вызова. (Просто увидел, что это было отмечено в комментарии ниже.)
Ответ 2
Это очень простой подход. Преимущество в том, что вы также можете получить ключи:
for (var key in array) {
var value = array[key];
console.log(key, value);
}
Для ES6:
array.forEach(value => {
console.log(value)
})
Для ES6: (если вам нужно значение, индекс и сам массив)
array.forEach((value, index, self) => {
console.log(value, index, self)
})
Ответ 3
arr_jq_TabContents[key]
видит массив как 0-индексную форму.
Ответ 4
Уже есть несколько простых примеров, но я заметил, как вы сформулировали свой вопрос, что вы, вероятно, пришли из фона PHP, и вы ожидаете, что JavaScript будет работать одинаково - это не так. PHP array
сильно отличается от JavaScript array
.
В PHP ассоциативный массив может выполнять большую часть массива с числовым индексом (функции array_*
работают, вы можете count()
его и т.д.). Вы просто создаете массив и начинаете назначать строковые индексы вместо числового.
В JavaScript все является объектом (за исключением примитивов: string, numeric, boolean), а массивы - это определенная реализация, которая позволяет вам иметь числовые индексы. Все, что помещается в массив, будет влиять на его length
и может быть повторено с использованием методов Array (map
, forEach
, reduce
, filter
, find
и т.д.). Однако, поскольку все объект, вы всегда можете просто назначать свойства, потому что это то, что вы делаете с любым объектом. Обозначение квадратной скобки - это просто еще один способ доступа к свойству, поэтому в вашем случае:
array['Main'] = 'Main Page';
фактически эквивалентен:
array.Main = 'Main Page';
Из вашего описания я предполагаю, что вы хотите "ассоциативный массив", но для JavaScript это простой случай использования объекта в качестве хэш-карты. Кроме того, я знаю это пример, но избегаю несущественных имен, которые описывают только тип переменной (например, array
) и имя, основанное на том, что он должен содержать (например, pages
). Простые объекты не имеют много хороших прямых путей для итерации, поэтому мы часто включаем в массивы сначала с помощью методов Object
(Object.keys
в этом случае - там также entries
и values
добавляются к некоторым браузеры прямо сейчас), которые мы можем выполнить.
// assigning values to corresponding keys
const pages = {
Main: 'Main page',
Guide: 'Guide page',
Articles: 'Articles page',
Forum: 'Forum board',
};
Object.keys(pages).forEach((page) => console.log(page));
Ответ 5
Вот простой способ использовать ассоциативный массив в качестве универсального типа объекта:
Object.prototype.forEach = function(cb){
if(this instanceof Array) return this.forEach(cb);
let self = this;
Object.getOwnPropertyNames(this).forEach(
(k)=>{ cb.call(self, self[k], k); }
);
};
Object({a:1,b:2,c:3}).forEach((value, key)=>{
console.log('key/value pair: ${key}/${value}');
});
Ответ 6
Если node.js или браузер поддерживают Object.entries()
, его можно использовать как альтернативу использованию Object.keys()
(fooobar.com/questions/51674/...).
const h = {
a: 1,
b: 2
};
Object.entries(h).forEach(([key, value]) => console.log(value));
// logs 1, 2
Ответ 7
var obj = {
no: ["no", 32],
nt: ["no", 32],
nf: ["no", 32, 90]
};
count = -1; // which must be static value
for (i in obj) {
count++;
if (obj.hasOwnProperty(i)) {
console.log(obj[i][count])
};
};
Ответ 8
Это (по сути) неправильно в большинстве случаев:
var array = [];
array["Main"] = "Main page";
Это создает неэлементное свойство в массиве с именем Main
. Хотя массивы являются объектами, обычно вы не хотите создавать для них неэлементные свойства.
Если вы хотите индексировать в array
по этим именам, обычно вы используете Map
или простой объект, а не массив.
С Map
(ES2015+), который я назову map
, потому что я креативен:
let map = new Map();
map.set("Main", "Main page");
вы затем выполняете итерацию с использованием итераторов из методов values
, keys
или entries
, например:
for (const value of map.values()) {
// Here, 'value' will be '"Main page"', etc.
}
Использование простого объекта, который я творчески назову obj
:
let obj = Object.create(null); // Creates an object with no prototype
obj.Main = "Main page"; // Or: 'obj["Main"] = "Main page";'
вы затем итерируете его содержимое, используя Object.keys
, Object.values
или Object.entries
, например:
for (const value of Object.values(proches_X)) {
// Here, 'value' will be '"Main page"', etc.
}
Ответ 9
Используйте цифровые клавиши. length
на Array
отслеживает только цифровые клавиши. Используйте Object
или Map
для пар ключ-значение.
var array = [];
// assigning values to corresponding keys
array[0] = "Main page";
array[1] = "Guide page";
array[2] = "Articles page";
array[3] = "Forum board";
for (var i = 0; i < array.length; i++) {
console.log(i); //0 1 2 3
//OR:
console.log(array[i]);
}