Самый эффективный способ создания нулевого заполненного массива JavaScript?

Каков наиболее эффективный способ создания массива произвольной длины с нулевым заполнением в JavaScript?

Ответ 1

ES6 представляет Array.prototype.fill. Это можно использовать так:

new Array(len).fill(0);

Не уверен, что это быстро, но мне это нравится, потому что оно короткое и самоописательное.

Это все еще не в IE (проверьте совместимость), но там есть полифилл.

Ответ 2

Хотя это старый поток, я хотел добавить к нему 2 цента. Не уверен, насколько это медленное/быстрое, но это быстрый один лайнер. Вот что я делаю:

Если я хочу предварительно заполнить цифрой:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
// [0, 0, 0, 0, 0]

Если я хочу предварительно заполнить строку:

Array.apply(null, Array(3)).map(String.prototype.valueOf,"hi")
// ["hi", "hi", "hi"]

Другие ответы предложили:

new Array(5+1).join('0').split('')
// ["0", "0", "0", "0", "0"]

но если вы хотите 0 (число), а не "0" (ноль внутри строки), вы можете сделать:

new Array(5+1).join('0').split('').map(parseFloat)
// [0, 0, 0, 0, 0]

Ответ 3

Элегантный способ заполнения массива с предварительно вычисленными значениями

Вот еще один способ сделать это с помощью ES6, о котором никто не упомянул:

> Array.from(Array(3), () => 0)
< [0, 0, 0]

Он работает, передавая функцию отображения в качестве второго параметра Array.from.

В приведенном выше примере первый параметр выделяет массив из трех позиций, заполненных значением undefined, а затем лямбда-функция сопоставляет каждый из них с значением 0.

Хотя Array(len).fill(0) короче, он не работает, если вам нужно заполнить массив, выполнив сначала некоторые вычисления (я знаю, что вопрос не запрашивал его, но многие люди в конечном итоге ищут это).

Например, если вам нужен массив с 10 случайными числами:

> Array.from(Array(10), () => Math.floor(10 * Math.random()))
< [3, 6, 8, 1, 9, 3, 0, 6, 7, 1]

Это более краткий (и элегантный), чем эквивалент:

const numbers = Array(10);
for (let i = 0; i < numbers.length; i++) {
    numbers[i] = Math.round(10 * Math.random());
}

Этот метод также можно использовать для генерации последовательностей чисел, используя параметр индекса, указанный в обратном вызове:

> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Бонусный ответ: заполните массив, используя String repeat()

Поскольку этот ответ получает большое внимание, я также хотел показать этот классный трюк. Хотя это не так полезно, как мой главный ответ, вы познакомитете еще не очень известный, но очень полезный метод String repeat(). Вот трюк:

> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]

Прохладный, да? repeat() - очень полезный метод для создания строки, которая является повторением исходной строки определенное количество раз. После этого split() создает для нас массив, который затем map() ped соответствует требуемым значениям. Разбивая его пошагово:

> "?".repeat(10)
< "??????????"

> "?".repeat(10).split("")
< ["?", "?", "?", "?", "?", "?", "?", "?", "?", "?"]

> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]

Ответ 4

Уже упомянутый метод заполнения ES 6 позаботится об этом. Большинство современных настольных браузеров уже поддерживают требуемые методы прототипов Array на сегодняшний день (Chromium, FF, Edge и Safari) [1]. Вы можете найти подробную информацию о MDN. Простой пример использования

a = new Array(10).fill(0);

Учитывая текущую поддержку браузера, вы должны быть осторожны, если вы не уверены, что ваша аудитория использует современные настольные браузеры.

Ответ 5

Примечание добавлено в августе 2013 года, обновлено в феврале 2015 года. Ниже приведен ответ, относящийся к 2009 году, к родовому типу JavaScript Array. Он не относится к новым массивам типизированных, определенным в ES2015 [и доступным теперь во многих браузерах], например Int32Array и тому подобное. Также обратите внимание, что ES2015 добавляет метод fill для Массивы и типизированные массивы, которые, вероятно, будут наиболее эффективным способом их заполнения...

Кроме того, это может иметь большое значение для некоторых реализаций, как вы создаете массив. Двигатель Chrome V8, в частности, пытается использовать высокоэффективный массив смежных массивов, если он думает, что может, переходя к объектно-ориентированному массиву только при необходимости.


В большинстве языков он будет предварительно назначаться, а затем заполнять нуль, например:

function newFilledArray(len, val) {
    var rv = new Array(len);
    while (--len >= 0) {
        rv[len] = val;
    }
    return rv;
}

Но, массивы JavaScript на самом деле не массивы, они являются ключевыми/значными картами, как и все другие объекты JavaScript, поэтому нет необходимости делать "предварительное выделение" (установка длины не означает, что заполняется множество слотов), и нет никаких оснований полагать, что преимущество подсчета до нуля (что должно сравнение в цикле быстро) не перевешивается добавлением ключей в обратном порядке, когда реализация может оптимизировать обработку ключей, связанных с массивами, по теории, которую вы обычно делаете в порядке.

Фактически, Мэтью Крамли отметил, что подсчет в Firefox заметно медленнее, чем подсчет, результат я могу подтвердить — это часть массива (цикл до нуля все еще быстрее, чем цикл до предела в var). Очевидно, что добавление элементов в массив в обратном порядке является медленным оператором в Firefox. Фактически, результаты значительно меняются при реализации JavaScript (что не удивительно). Здесь быстро и грязная тестовая страница (ниже) для реализаций браузера (очень грязная, не дает во время тестов, поэтому обеспечивает минимальную обратную связь и будет работать с временными ограничениями script). Я рекомендую обновлять между тестами; FF (по крайней мере) замедляет повторные тесты, если вы этого не делаете.

Довольно сложная версия, использующая Array # concat, быстрее, чем прямой init на FF, где-то от 1000 до 2000 элементов массивов. На движке Chrome V8 каждый раз каждый подряд выигрывает прямой init...

Здесь тестовая страница (живая копия):

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Zero Init Test Page</title>
<style type='text/css'>
body {
    font-family:    sans-serif;
}
#log p {
    margin:     0;
    padding:    0;
}
.error {
    color:      red;
}
.winner {
    color:      green;
    font-weight:    bold;
}
</style>
<script type='text/javascript' src='prototype-1.6.0.3.js'></script>
<script type='text/javascript'>
var testdefs = {
    'downpre':  {
        total:  0,
        desc:   "Count down, pre-decrement",
        func:   makeWithCountDownPre
    },
    'downpost': {
        total:  0,
        desc:   "Count down, post-decrement",
        func:   makeWithCountDownPost
    },
    'up':       {
        total:  0,
        desc:   "Count up (normal)",
        func:   makeWithCountUp
    },
    'downandup':  {
        total:  0,
        desc:   "Count down (for loop) and up (for filling)",
        func:   makeWithCountDownArrayUp
    },
    'concat':   {
        total:  0,
        desc:   "Concat",
        func:   makeWithConcat
    }
};

document.observe('dom:loaded', function() {
    var markup, defname;

    markup = "";
    for (defname in testdefs) {
        markup +=
            "<div><input type='checkbox' id='chk_" + defname + "' checked>" +
            "<label for='chk_" + defname + "'>" + testdefs[defname].desc + "</label></div>";
    }
    $('checkboxes').update(markup);
    $('btnTest').observe('click', btnTestClick);
});

function epoch() {
    return (new Date()).getTime();
}

function btnTestClick() {

    // Clear log
    $('log').update('Testing...');

    // Show running
    $('btnTest').disabled = true;

    // Run after a pause while the browser updates display
    btnTestClickPart2.defer();
}
function btnTestClickPart2() {

    try {
        runTests();
    }
    catch (e) {
        log("Exception: " + e);
    }

    // Re-enable the button; we don't yheidl
    $('btnTest').disabled = false;
}

function runTests() {
    var start, time, counter, length, defname, def, results, a, invalid, lowest, s;

    // Get loops and length
    s = $F('txtLoops');
    runcount = parseInt(s);
    if (isNaN(runcount) || runcount <= 0) {
        log("Invalid loops value '" + s + "'");
        return;
    }
    s = $F('txtLength');
    length = parseInt(s);
    if (isNaN(length) || length <= 0) {
        log("Invalid length value '" + s + "'");
        return;
    }

    // Clear log
    $('log').update('');

    // Do it
    for (counter = 0; counter <= runcount; ++counter) {

        for (defname in testdefs) {
            def = testdefs[defname];
            if ($('chk_' + defname).checked) {
                start = epoch();
                a = def.func(length);
                time = epoch() - start;
                if (counter == 0) {
                    // Don't count (warm up), but do check the algorithm works
                    invalid = validateResult(a, length);
                    if (invalid) {
                        log("<span class='error'>FAILURE</span> with def " + defname + ": " + invalid);
                        return;
                    }
                }
                else {
                    // Count this one
                    log("#" + counter + ": " + def.desc + ": " + time + "ms");
                    def.total += time;
                }
            }
        }
    }

    for (defname in testdefs) {
        def = testdefs[defname];
        if ($('chk_' + defname).checked) {
            def.avg = def.total / runcount;
            if (typeof lowest != 'number' || lowest > def.avg) {
                lowest = def.avg;
            }
        }
    }

    results =
        "<p>Results:" +
        "<br>Length: " + length +
        "<br>Loops: " + runcount +
        "</p>";
    for (defname in testdefs) {
        def = testdefs[defname];
        if ($('chk_' + defname).checked) {
            results += "<p" + (lowest == def.avg ? " class='winner'" : "") + ">" + def.desc + ", average time: " + def.avg + "ms</p>";
        }
    }
    results += "<hr>";
    $('log').insert({top: results});
}

function validateResult(a, length) {
    var n;

    if (a.length != length) {
        return "Length is wrong";
    }
    for (n = length - 1; n >= 0; --n) {
        if (a[n] != 0) {
            return "Index " + n + " is not zero";
        }
    }
    return undefined;
}

function makeWithCountDownPre(len) {
    var a;

    a = new Array(len);
    while (--len >= 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountDownPost(len) {
    var a;

    a = new Array(len);
    while (len-- > 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountUp(len) {
    var a, i;

    a = new Array(len);
    for (i = 0; i < len; ++i) {
        a[i] = 0;
    }
    return a;
}

function makeWithCountDownArrayUp(len) {
    var a, i;

    a = new Array(len);
    i = 0;
    while (--len >= 0) {
        a[i++] = 0;
    }
    return a;
}

function makeWithConcat(len) {
    var a, rem, currlen;

    if (len == 0) {
        return [];
    }
    a = [0];
    currlen = 1;
    while (currlen < len) {
        rem = len - currlen;
        if (rem < currlen) {
            a = a.concat(a.slice(0, rem));
        }
        else {
            a = a.concat(a);
        }
        currlen = a.length;
    }
    return a;
}

function log(msg) {
    $('log').appendChild(new Element('p').update(msg));
}
</script>
</head>
<body><div>
<label for='txtLength'>Length:</label><input type='text' id='txtLength' value='10000'>
<br><label for='txtLoops'>Loops:</label><input type='text' id='txtLoops' value='10'>
<div id='checkboxes'></div>
<br><input type='button' id='btnTest' value='Test'>
<hr>
<div id='log'></div>
</div></body>
</html>

Ответ 6

SHORTEST

Array(n).fill(0)

(16 символов), где n - размер массива


2018.10.28 я сделал сравнение производительности 15 предложений из других ответов. Тестирование проводилось на Mac OS X 10.13.6 High Sierra, в трех браузерах: Chrome 69.0.3497, Safari 12.0 (13606.2.11) и Firefox 63.0 (64-разрядная версия).

Результат для n = 100000

Ниже я показываю результаты для самого быстрого браузера (сафари):

enter image description here enter image description here

Для всех браузеров самым быстрым решением было M - однако это не "типичный массив" (но очень быстрый) - Safari 33,8 тыс. Операций в секунду, Chrome 5,2 тыс., FF 3,5 тыс.,

Самые быстрые решения для типичных массивов:

  • A и B (было похоже) для Safari 5.5k и Chrome 1.1k (в Firefox A 0,1k, B 0,06k)
  • F для Firefox 0.6k (в Safari 3.1k, Chrome 1.1k)
  • для Chrome и Safari результаты A, B, F были близки

Самое медленное решение:

  • G для Safari 0.02k и Firefox 0.04k (в Chrome 0.1k)
  • D для Chrome 0.04k (в Safari 0.33k, в Firefox 0.15k)

Решение N работает только в Firefox и Chrome.

Результат для n = 10

Самый быстрый:

  • M был самым быстрым в Chrome 17.3M и Safari 13.3M (Firefox 4.7M)
  • A, B был аналогичным и быстрым на Firefox 16,9M (Chrome 15,6M, Safari 3,5M)

Slowest:

  • O для Safari 0,35M
  • K для Chrome 0.35M
  • N для Firefox 0.31M

ЗАКЛЮЧЕНИЕ

  • самым быстрым решением во всех браузерах (кроме маленького n в Firefox) было M let a = new Float32Array(n) (однако это не типичный массив) - для него самым быстрым браузером был Safari (для больших n> в 6 раз быстрее чем Chrome,> в 9 раз быстрее Firefox)
  • для типичных массивов предпочтительным решением является A let a = Array(n).fill(0) (быстрый и короткий код)

Вы можете выполнить тестирование на своем компьютере здесь.

Ответ 7

По умолчанию классы Uint8Array, Uint16Array и Uint32Array сохраняют нули в качестве своих значений, поэтому вам не нужны сложные методы заполнения, просто выполните:

var ary = new Uint8Array(10);

все элементы массива ary по умолчанию будут нулями.

Ответ 8

Если вы используете ES6, вы можете использовать Array.from() следующим образом:

Array.from({ length: 3 }, () => 0);
//[0, 0, 0]

Имеет тот же результат, что и

Array.from({ length: 3 }).map(() => 0)
//[0, 0, 0]

Так как

Array.from({ length: 3 })
//[undefined, undefined, undefined]

Ответ 9

function makeArrayOf(value, length) {
  var arr = [], i = length;
  while (i--) {
    arr[i] = value;
  }
  return arr;
}

makeArrayOf(0, 5); // [0, 0, 0, 0, 0]

makeArrayOf('x', 3); // ['x', 'x', 'x']

Обратите внимание, что while обычно более эффективен, чем for-in, forEach и т.д.

Ответ 10

Я тестировал все комбинации предварительного выделения/не предварительного выделения, подсчета вверх/вниз и для циклов /while в IE 6/7/8, Firefox 3.5, Chrome и Opera.

Функции ниже были последовательно самыми быстрыми или чрезвычайно близкими в Firefox, Chrome и IE8 и не намного медленнее, чем самые быстрые в Opera и IE 6. Это также самое простое и ясное на мой взгляд. Я нашел несколько браузеров, где версия цикла while немного быстрее, поэтому я тоже включаю ее для справки.

function newFilledArray(length, val) {
    var array = [];
    for (var i = 0; i < length; i++) {
        array[i] = val;
    }
    return array;
}

или

function newFilledArray(length, val) {
    var array = [];
    var i = 0;
    while (i < length) {
        array[i++] = val;
    }
    return array;
}

Ответ 11

с использованием объектной нотации

var x = [];

нуль заполнен? как...

var x = [0,0,0,0,0,0];

заполненный 'undefined'...

var x = new Array(7);

Обозначение с нулями

var x = [];
for (var i = 0; i < 10; i++) x[i] = 0;

В качестве побочного примечания, если вы измените прототип Array, оба

var x = new Array();

и

var y = [];

будут иметь модификации прототипов

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

Ответ 12

function zeroFilledArray(size) {
    return new Array(size + 1).join('0').split('');
}

Ответ 13

Если вам нужно создать много нулевых заполненных массивов разной длины во время выполнения вашего кода, самый быстрый способ, который я нашел для этого, - создать нулевой массив один раз, используя один из методы, упомянутые в этой теме, длины, которую вы знаете, никогда не будут превышены, а затем разрезайте этот массив по мере необходимости.

Например (используя функцию из выбранного ответа выше, чтобы инициализировать массив), создайте нулевой заполненный массив длины maxLength, как переменную, видимую для кода, которому нужны нулевые массивы:

var zero = newFilledArray(maxLength, 0);

Теперь разрезайте этот массив каждый раз, когда вам нужен нулевой заполненный массив длины Length < MAXLENGTH:

zero.slice(0, requiredLength);

Я создавал нулевые заполненные массивы тысячи раз во время выполнения моего кода, это значительно ускорило процесс.

Ответ 14

У меня нет ничего против:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
new Array(5+1).join('0').split('').map(parseFloat);

предложенный Zertosh, но в расширениях новых ES6 вы можете сделать это изначально с помощью метода fill. Теперь край IE, Chrome и FF поддерживают его, но проверьте таблицу совместимости

new Array(3).fill(0) даст вам [0, 0, 0]. Вы можете заполнить массив любым значением, например new Array(5).fill('abc') (даже объекты и другие массивы).

Кроме того, вы можете изменить предыдущие массивы с помощью fill:

arr = [1, 2, 3, 4, 5, 6]
arr.fill(9, 3, 5)  # what to fill, start, end

который дает вам: [1, 2, 3, 9, 9, 6]

Ответ 15

Как обычно я это делаю (и очень быстро) использует Uint8Array. Например, создавая вектор с нулевым заполнением из 1M элементов:

  var zeroFilled = [].slice.apply(new Uint8Array(1000000))

Я пользователь Linux и всегда работал у меня, но как только у друга, использующего Mac, были некоторые ненулевые элементы. Я думал, что его машина работает неправильно, но все же здесь самый безопасный способ, который мы нашли, чтобы исправить это:

  var zeroFilled = [].slice.apply(new Uint8Array(new Array(1000000)) 

Edited

Chrome 25.0.1364.160

  • Фредерик Готлиб - 6.43
  • Сэм Барнум - 4.83
  • Eli - 3.68
  • Джошуа 2.91
  • Мэтью Крамли - 2.67
  • bduran - 2.55
  • Аллен Райс - 2.11
  • kangax - 0.68
  • Tj. Кроудер - 0,67
  • zertosh - ОШИБКА

Firefox 20.0

  • Аллен Райс - 1.85
  • Джошуа - 1.82
  • Мэтью Крамли - 1.79
  • bduran - 1.37
  • Фредерик Готлиб - 0,67
  • Сэм Барнум - 0,63
  • Eli - 0.59
  • kagax - 0.13
  • Tj. Кроудер - 0,13
  • zertosh - ОШИБКА

Отсутствует самый важный тест (по крайней мере для меня): Node.js. Я подозреваю, что это близко к эталону Chrome.

Ответ 16

Решение ES6:

[...new Array(5)].map(x => 0); // [0, 0, 0, 0, 0]

Ответ 17

Начиная с ECMAScript2016, существует один четкий выбор для больших массивов.

Поскольку этот ответ по-прежнему отображается в верхней части результатов поиска Google, здесь представлен ответ на 2017 год.

Вот текущий jsbench с несколькими десятками популярных методов, в том числе многие предложенные до сих пор по этому вопросу. Если вы найдете лучший способ, пожалуйста, добавьте, раскошелиться и поделиться.

Я хочу отметить, что не существует истинного наиболее эффективного способа создания массива произвольной длины с нулевым заполнением. Вы можете оптимизировать скорость, ясность и ремонтопригодность - и то, и другое можно считать более эффективным выбором в зависимости от потребностей проекта.

При оптимизации по скорости вы хотите: создать массив с использованием буквального синтаксиса; установите длину, инициализируйте переменную итерации и выполните итерацию по массиву, используя цикл while. Вот пример.

const arr = [];
arr.length = 120000;
let i = 0;
while (i < 120000) {
  arr[i] = 0;
  i++;
}

Ответ 18

Используя lodash или underscore

_.range(0, length - 1, 0);

Или, если у вас есть массив, и вы хотите иметь массив с одинаковой длиной

array.map(_.constant(0));

Ответ 19

Чтобы создать полностью новый массив

new Array(arrayLength).fill(0);

Чтобы добавить некоторые значения в конец существующего массива

[...existingArray, ...new Array(numberOfElementsToAdd).fill(0)]

Пример

//**To create an all new Array**

console.log(new Array(5).fill(0));

//**To add some values at the end of an existing Array**

let existingArray = [1,2,3]

console.log([...existingArray, ...new Array(5).fill(0)]);

Ответ 20

Как насчет new Array(51).join('0').split('')?

Ответ 21

Не видел этот метод в ответах, поэтому вот он:

"0".repeat( 200 ).split("").map( parseFloat )

В результате вы получите нулевой массив длиной 200:

[ 0, 0, 0, 0, ... 0 ]

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

Ответ 22

Моя самая быстрая функция:

function newFilledArray(len, val) {
    var a = [];
    while(len--){
        a.push(val);
    }
    return a;
}

var st = (new Date()).getTime();
newFilledArray(1000000, 0)
console.log((new Date()).getTime() - st); // returned 63, 65, 62 milliseconds

Использование встроенного push и shift для добавления элементов в массив выполняется намного быстрее (примерно в 10 раз), чем объявление области массива и привязка каждого элемента, чтобы установить его значение.

fyi: я последовательно получаю более быстрое время с первым циклом, который отсчитывает, при запуске этого в firebug (расширение firefox).

var a = [];
var len = 1000000;
var st = (new Date()).getTime();
while(len){
    a.push(0);
    len -= 1;
}
console.log((new Date()).getTime() - st); // returned 863, 894, 875 milliseconds
st = (new Date()).getTime();
len = 1000000;
a = [];
for(var i = 0; i < len; i++){
    a.push(0);
}
console.log((new Date()).getTime() - st); // returned 1155, 1179, 1163 milliseconds

Мне интересно узнать, что такое T.J. Это делает Кроудер?: -)

Ответ 23

Эта версия concat намного быстрее в моих тестах в Chrome (2013-03-21). Около 200 мс для 10 000 000 элементов против 675 для прямого init.

function filledArray(len, value) {
    if (len <= 0) return [];
    var result = [value];
    while (result.length < len/2) {
        result = result.concat(result);
    }
    return result.concat(result.slice(0, len-result.length));
}

Бонус:, если вы хотите заполнить свой массив строками, это краткий способ сделать это (не так быстро, как concat хотя):

function filledArrayString(len, value) {
    return new Array(len+1).join(value).split('');
}

Ответ 24

Я тестировал отличный ответ T.J. Crowder, и придумал рекурсивное слияние на основе решения concat, которое превосходит любые его тесты в Chrome (я не тестировал другие браузеры).

function makeRec(len, acc) {
    if (acc == null) acc = [];
    if (len <= 1) return acc;
    var b = makeRec(len >> 1, [0]);
    b = b.concat(b);
    if (len & 1) b = b.concat([0]);
    return b;
},

вызов метода с помощью makeRec(29).

Ответ 25

Самый короткий для кода цикла

a=i=[];for(;i<100;)a[i++]=0;

edit:
for(a=i=[];i<100;)a[i++]=0;
or
for(a=[],i=100;i--;)a[i]=0;

Безопасная версия var

var a=[],i=0;for(;i<100;)a[i++]=0;

edit:
for(var i=100,a=[];i--;)a[i]=0;

Ответ 26

Я знал, что у меня есть этот proto'd где-то:)

Array.prototype.init = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this[n] = x; }
    return this;
}

var a = (new Array(5)).init(0);

var b = [].init(0,4);

Изменить: тесты

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

Вот что я тестировал:

//my original method
Array.prototype.init = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this[n] = x; }
    return this;
}

//now using push which I had previously thought to be slower than direct assignment
Array.prototype.init2 = function(x,n)
{
    if(typeof(n)=='undefined') { n = this.length; }
    while (n--) { this.push(x); }
    return this;
}

//joshua method
function newFilledArray(len, val) {
    var a = [];
    while(len--){
        a.push(val);
    }
    return a;
}

//test m1 and m2 with short arrays many times 10K * 10

var a = new Date();
for(var i=0; i<10000; i++)
{
    var t1 = [].init(0,10);
}
var A = new Date();

var b = new Date();
for(var i=0; i<10000; i++)
{
    var t2 = [].init2(0,10);
}
var B = new Date();

//test m1 and m2 with long array created once 100K

var c = new Date();
var t3 = [].init(0,100000);
var C = new Date();

var d = new Date();
var t4 = [].init2(0,100000);
var D = new Date();

//test m3 with short array many times 10K * 10

var e = new Date();
for(var i=0; i<10000; i++)
{
    var t5 = newFilledArray(10,0);
}
var E = new Date();

//test m3 with long array created once 100K

var f = new Date();
var t6 = newFilledArray(100000, 0)
var F = new Date();

Результаты:

IE7 deltas:
dA=156
dB=359
dC=125
dD=375
dE=468
dF=412

FF3.5 deltas:
dA=6
dB=13
dC=63
dD=8
dE=12
dF=8

Таким образом, мой расчетный толчок действительно медленнее, но лучше работает с более длинными массивами в FF, но хуже в IE, который просто отстой вообще (quel surprise).

Ответ 27

Возможно, стоит отметить, что Array.prototype.fill был добавлен как часть Предложение ECMAScript 6 (Гармония). Я предпочел бы пойти с polyfill, написанным ниже, прежде чем рассматривать другие варианты, упомянутые в потоке.

if (!Array.prototype.fill) {
  Array.prototype.fill = function(value) {

    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length >>> 0;

    // Steps 6-7.
    var start = arguments[1];
    var relativeStart = start >> 0;

    // Step 8.
    var k = relativeStart < 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 9-10.
    var end = arguments[2];
    var relativeEnd = end === undefined ?
      len : end >> 0;

    // Step 11.
    var final = relativeEnd < 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 12.
    while (k < final) {
      O[k] = value;
      k++;
    }

    // Step 13.
    return O;
  };
}

Ответ 28

let filled = [];
filled.length = 10;
filled.fill(0);

console.log(filled);

Ответ 29

var str = "0000000...0000";
var arr = str.split("");

использование в выражениях: arr[i]*1;

EDIT: если arr предполагается использовать в целых выражениях, то, пожалуйста, не обращайте внимание на значение char '0'. Вы просто используете его следующим образом: a = a * arr[i] (предполагая, что a имеет целочисленное значение).

Ответ 30

Всегда существует решение phpjs, которое вы можете найти здесь:

http://phpjs.org/functions/array_fill/

Я не могу говорить о проекте (создавая библиотеку функций javascript, которая отражает большую функциональность php) в целом, но несколько функций, которые я лично вытащил оттуда, работали как чемпион.