Массив JS, используемый во второй раз, имеет длину, равную ‘0’, но содержит объекты

#javascript #arrays

#javascript #массивы

Вопрос:

Описание:

  • Два массива ( arrNumber массив чисел и arrString массив строк).
  • arrNumber Используется для добавления списка объектов с ключом (числом или символом) и счетчиком повторяющихся значений.

Проблема:

  • В первый раз arrDuplicateValues все в порядке, но во второй раз массив имеет длину, равную 0, но содержит элементы.

https://jsbin.com/qevuxopoma/edit?js консоль

 var arrNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 0 ,4, 6, 8, 4];
var arrString = ["a", "e", "i", "o", "u", "a", "i", "u", "i"];

var arrDuplicateValues = new Array();
// Fist time: Only number
arrNumber.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // OK


// Second time: With string
arrDuplicateValues = new Array();
arrString.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // NOK
console.log(arrDuplicateValues["i"]);  

Комментарии:

1. Массивы используют числовые индексы для элементов. Использование строк просто добавляет свойства объекту, но не добавляет элементы в массив.

2. На самом деле вам не следует использовать массив, если вы не хотите последовательно располагать свойства с числовым индексом. Ваш второй пример просто добавляет строковые ключи. Они существуют в объекте array, но не увеличивают его длину.

3. Не используйте new Array() (это почти наверняка делает не то, что вы думаете), используйте обычный синтаксис JS для выделения нового массива: var/let/const thing = []; . Кроме того, массивы — это индексированные списки в JS, массивы не похожи на PHP, где они могут быть как индексированными, так и «ассоциативными массивами» (с использованием строковых ключей): в JS основным типом данных для данных со строковым ключом является object, который использует {} синтаксис.

Ответ №1:

Здесь вы хотите использовать объекты, а не массивы. Потому что массивы представляют собой списки с индексом.

Рабочий пример:

 var arrNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 0 ,4, 6, 8, 4];
var arrString = ["a", "e", "i", "o", "u", "a", "i", "u", "i"];

var arrDuplicateValues = {};
// Fist time: Only number
arrNumber.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // OK


// Second time: With string
arrDuplicateValues = {};
arrString.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // NOK
console.log(arrDuplicateValues["i"]);  

Ответ №2:

arrDuplicateValues является объектом во второй раз, потому что массив не имеет строкового индекса. Итак, хотя вы инициализировали его Array (), в конечном итоге он стал картой (пара ключ-значение), следовательно, когда вы просто попытались распечатать всю карту, это ничего не дало. Если вы просто измените инициализацию на arrDuplicateValues = {}; второй раз, все будет работать нормально.

 var arrNumber = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 2, 4, 6, 8, 0 ,4, 6, 8, 4];
var arrString = ["a", "e", "i", "o", "u", "a", "i", "u", "i"];

var arrDuplicateValues = new Array();
// Fist time: Only number
arrNumber.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // OK


// Second time: With string
arrDuplicateValues = {};
arrString.forEach(x => {
  arrDuplicateValues[x] = (arrDuplicateValues[x] || 0)   1;
});
console.log(arrDuplicateValues); // NOK
console.log(arrDuplicateValues["i"]);