Чи існує більш компактний спосіб зробити такий різновид ініціалізації?
for (var i = 0; i < arraySize; i++) array[i] = value;
Чи існує більш компактний спосіб зробити такий різновид ініціалізації?
for (var i = 0; i < arraySize; i++) array[i] = value;
Відповіді:
while(arraySize--) array.push(value);
відсутність ініціалізації (про яку я знаю)
Оновлення
З тих пір, як колись публікували цю відповідь 4 роки тому, люди, здається, постійно повертаються сюди за цією відповіддю. Для порівняльних цілей я створив JSPerf з різними рішеннями.
Рішення вище не найшвидше, хоча воно і коротке. Щоб дотримуватися того самого короткого стилю, але з кращими показниками:
while(size--) array[size] = value;
Оновлення лютого 2016 р. Оновлено JSPerf новою версією з більшою кількістю тестових випадків.
Якщо продуктивність не має значення, і ви хочете однокласний:
var value = 1234, // can be replaced by a fixed value
size = 1000, // can be replaced by a fixed value
array = Array.apply(null,{length: size}).map(function() { return value; });
Більш ефективне рішення (в одному, брудному, рядку): Майте на увазі: це замінює існуючі значення, розмір та i змінні в області
for(var i = 0, value = 1234, size = 1000, array = new Array(1000); i < size; i++) array[i] = value;
whileв 2 рази повільніше, ніж forу JavaScript, а прості перевірки на кшталт if (number)також повільніші, ніж if (number === 0)через перетворення типу (це також стосується булевих значень, рядків та нулів). Цьому мене навчили мої тести jsPerf.
Короткий спосіб зробити це:
var arr = Array(arraySize).fill(value);
Зробив би arr = Array [ 0, 0, 0, 0, 0 ]якщо arraySize == 5і value == 0, наприклад.
Здається, ОП вимагає компактності в сценарії одноразового використання щодо ефективності та повторного використання. Для інших, хто шукає ефективності, ось оптимізація, про яку ще не згадувалося. Оскільки ви заздалегідь знаєте довжину масиву, продовжуйте і встановлюйте його перед присвоєнням значень. В іншому випадку масив буде неодноразово змінюватись на льоту - не ідеально!
function initArray(length, value) {
var arr = [], i = 0;
arr.length = length;
while (i < length) { arr[i++] = value; }
return arr;
}
var data = initArray(1000000, false);
forце в 2 рази швидше, ніж while.
Це не настільки компактно, але, можливо, є більш прямим.
array = Array.apply(null, new Array(arraySize)).map(function () {return value;});
Це, швидше за все, не буде кращим за будь-який із наведених вище методів, але це цікаво ...
var a = new Array(10).join('0').split('').map(function(e) {return parseInt(e, 10);})
var arr = (new Array(5)).map(() => 1);не працює?
new Array(5)як ми робимо карту, чи не оперуємо ми масивом? Крім того, це [1,undefined,3].map(() => 5)працює, як очікувалося. Це не пропускаєundefined
Для ефективності я б уникав push. Так просто
for (var i = 0; i < arraySize; i++) array[i] = value;
Для IE10:
array = new Array(arraySize);
for (var i = 0; i < arraySize; i++) array[i] = value;
Редагувати: змінено, як обговорювалось у коментарях.
for (var i = 0; i < arraySize; ++i)має майже таку ж продуктивність, як і ваш код, але виглядає чистішим. Але while (arraySize--)це в 2 рази повільніше.
arrayбільш ефективний, ніж запуск array[0].
Якщо вам потрібно це зробити багато разів, ви завжди можете написати функцію:
function makeArray(howMany, value){
var output = [];
while(howMany--){
output.push(value);
}
return output;
}
var data = makeArray(40, "Foo");
І лише для повноти (возитися з прототипом вбудованих об’єктів часто не є гарною ідеєю):
Array.prototype.fill = function(howMany, value){
while(howMany--){
this.push(value);
}
}
Тож тепер ви можете:
var data = [];
data.fill(40, "Foo");
Оновлення: Я щойно бачив вашу нотатку про arraySizeте, що це константа або буквал. Якщо так, просто замініть усіх while(howMany--)на старі добрі for(var i=0; i<howMany; i++).
Натрапивши на це, досліджуючи масивні методи на літаку .. ооо, місця, куди ми їдемо, коли нам нудно. :)
var initializedArray = new Array(30).join(null).split(null).map(function(item, index){
return index;
});
.map()і nullдля перемоги! Мені подобається null, тому що передача в рядок, як вгорі, з "0" або будь-яким іншим значенням заплутує. Я думаю, це більш чітко, що ми робимо щось інше.
Зверніть увагу, що .map()пропускає неініціалізовані значення. Ось чому new Array(30).map(function(item, index){return index});не працює. Новий .fill()метод є кращим, якщо він доступний, однак підтримка браузера повинна бути зазначена станом на 23.08.2015 .
Робочий стіл (базова підтримка)
З MDN :
[1, 2, 3].fill(4); // [4, 4, 4]
[1, 2, 3].fill(4, 1); // [1, 4, 4]
[1, 2, 3].fill(4, 1, 2); // [1, 4, 3]
[1, 2, 3].fill(4, 1, 1); // [1, 2, 3]
[1, 2, 3].fill(4, -3, -2); // [4, 2, 3]
[1, 2, 3].fill(4, NaN, NaN); // [1, 2, 3]
Array(3).fill(4); // [4, 4, 4]
[].fill.call({ length: 3 }, 4); // {0: 4, 1: 4, 2: 4, length: 3}
[...Array(30)].map((_, i) => i);