创建零填充JavaScript数组的最有效方法?

在JavaScript中创建任意长度的零填充数组的最有效方法是什么?

JinJin伽罗小胖2020/03/12 12:38:56

I just use :

var arr = [10];
for (var i=0; i<=arr.length;arr[i] = i, i++);
番长猴子古一2020/03/12 12:38:56

Shortest for loop code

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;

Safe var version

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

edit:
for(var i=100,a=[];i--;)a[i]=0;
凯樱2020/03/12 12:38:56

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

console.log(filled);

达蒙樱2020/03/12 12:38:56

This concat version is much faster in my tests on Chrome (2013-03-21). About 200ms for 10,000,000 elements vs 675 for straight 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));
}

Bonus: if you want to fill your array with Strings, this is a concise way to do it (not quite as fast as concat though):

function filledArrayString(len, value) {
    return new Array(len+1).join(value).split('');
}
谷若汐2020/03/12 12:38:56

ES6 solution:

[...new Array(5)].map(x => 0); // [0, 0, 0, 0, 0]
ProTony2020/03/12 12:38:56

To create an all new Array

new Array(arrayLength).fill(0);

To add some values at the end of an existing Array

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

Example

//**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)]);

Mandy伽罗2020/03/12 12:38:56

Using lodash or underscore

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

Or if you have an array existing and you want an array of the same length

array.map(_.constant(0));
村村AL2020/03/12 12:38:56

如果您需要在执行代码期间创建许多不同长度的零填充数组,我发现实现此目标的最快方法是使用本主题中提到的一种方法,一次创建一个零数组,其长度为您知道永远不会超出它,然后根据需要切片该数组。

例如(使用上面选择的答案中的函数初始化数组),创建一个长度为maxLength的零填充数组,作为需要零数组的代码可见的变量:

var zero = newFilledArray(maxLength, 0);

现在,每当您需要长度为requiredLength < maxLength的零填充数组时,就对它进行切片

zero.slice(0, requiredLength);

在执行代码期间,我数千次创建了零填充数组,这极大地加快了处理速度。

猿小小2020/03/12 12:38:55

我已经测试了IE 6/7/8,Firefox 3.5,Chrome和Opera中预分配/不预分配,向上/向下计数以及for / while循环的所有组合。

下面的功能始终是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;
}
木千2020/03/12 12:38:55

使用对象符号

var x = [];

零填充?喜欢...

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

充满“未定义” ...

var x = new Array(7);

带有零的obj符号

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

附带说明一下,如果您修改Array的原型,

var x = new Array();

var y = [];

将进行原型修改

无论如何,我不会过分担心此操作的效率或速度,您可能会做很多其他事情,这些事情比实例化包含零的任意长度的数组要浪费得多,也更昂贵。

梅老丝2020/03/12 12:38:55

用预先计算的值填充数组的优雅方法

到目前为止,还没有人提到使用ES6的另一种方法:

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

通过将map函数作为的第二个参数来工作Array.from

在上面的示例中,第一个参数分配一个由3个位置填充的数组,该位置填充了值undefined,然后lambda函数将其中的每个映射到value 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());
}

通过利用回调中提供的index参数,此方法还可用于生成数字序列:

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

奖励答案:使用字符串填充数组 repeat()

由于这个答案引起了广泛关注,因此我也想展示这个很酷的技巧。虽然不如我的主要回答有用,但将介绍仍然不是很了解,但是非常有用的String repeat()方法。这是窍门:

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

Cool, huh? repeat() is a very useful method to create a string that is the repetition of the original string a certain number of times. After that, split() creates an array for us, which is then map()ped to the values we want. Breaking it down in steps:

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

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

> "?".repeat(10).split("").map(() => Math.floor(10 * Math.random()))
< [5, 6, 3, 5, 0, 8, 2, 7, 4, 1]
斯丁JinJinHarry2020/03/12 12:38:55

已经提到的ES 6填充方法很好地解决了这一问题。到目前为止,大多数现代桌面浏览器已经支持所需的Array原型方法(Chromium,FF,Edge和Safari)[ 1 ]。您可以在MDN上查找详细信息一个简单的用法示例是

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

鉴于当前的浏览器支持,除非您确定您的受众使用的是现代桌面浏览器,否则应谨慎使用。

Mandy宝儿2020/03/12 12:38:55

如果使用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]
Ss Yy2020/03/12 12:38:55

默认情况下Uint8ArrayUint16ArrayUint32Array类将零作为其值,因此您不需要任何复杂的填充技术,只需执行以下操作:

var ary = new Uint8Array(10);

ary默认情况下,数组的所有元素将为零。

A小卤蛋Pro2020/03/12 12:38:55

SHORTEST

Array(n).fill(0)

(16 char), where n is size of array


2018.10.28 i made performance comparison of 15 propositions from other answers. Tests was done on Mac OS X 10.13.6 High Sierra, on three browsers: Chrome 69.0.3497, Safari 12.0 (13606.2.11) and Firefox 63.0 (64 bit).

Result for n=100000

Below i show results for fastest browser (safari):

在此处输入图片说明 在此处输入图片说明

For all browsers the fastest solution was M - however it is not "typical array" (but very fast) - Safari 33.8k operations/second, Chrome 5.2k, FF 3.5k,

Fastest solutions for typical arrays:

  • A and B (was similar) for Safari 5.5k and Chrome 1.1k (on Firefox A 0.1k, B 0.06k)
  • F for Firefox 0.6k (on Safari 3.1k, Chrome 1.1k)
  • for Chrome and Safari A,B,F results was close

The slowest solution:

  • G for Safari 0.02k and Firefox 0.04k (on Chrome 0.1k)
  • D for Chrome 0.04k (on Safari 0.33k, on Firefox 0.15k)

Solution N works only on Firefox and Chrome.

Result for n=10

Fastest:

  • M was fastest on Chrome 17.3M and Safari 13.3M (Firefox 4.7M)
  • A,B was similar and fastest on Firefox 16.9M (Chrome 15.6M, Safari 3.5M)

Slowest:

  • O for Safari 0.35M
  • K for Chrome 0.35M
  • N for Firefox 0.31M

CONCLUSION

  • the fastest solution on all browsers (except small n on Firefox) was M let a = new Float32Array(n) (however is not typical array) - for it the fastest browser was Safari (for large n >6x faster than Chrome, >9x faster than firefox)
  • 对于典型的数组,首选解决方案是A let a = Array(n).fill(0)(快速和短代码)

您可以在此处对机器进行测试