在JavaScript中创建任意长度的零填充数组的最有效方法是什么?
创建零填充JavaScript数组的最有效方法?
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;
let filled = [];
filled.length = 10;
filled.fill(0);
console.log(filled);
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('');
}
ES6 solution:
[...new Array(5)].map(x => 0); // [0, 0, 0, 0, 0]
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)]);
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));
如果您需要在执行代码期间创建许多不同长度的零填充数组,我发现实现此目标的最快方法是使用本主题中提到的一种方法,一次创建一个零数组,其长度为您知道永远不会超出它,然后根据需要切片该数组。
例如(使用上面选择的答案中的函数初始化数组),创建一个长度为maxLength的零填充数组,作为需要零数组的代码可见的变量:
var zero = newFilledArray(maxLength, 0);
现在,每当您需要长度为requiredLength < maxLength的零填充数组时,就对它进行切片:
zero.slice(0, requiredLength);
在执行代码期间,我数千次创建了零填充数组,这极大地加快了处理速度。
我已经测试了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;
}
使用对象符号
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 = [];
将进行原型修改
无论如何,我不会过分担心此操作的效率或速度,您可能会做很多其他事情,这些事情比实例化包含零的任意长度的数组要浪费得多,也更昂贵。
用预先计算的值填充数组的优雅方法
到目前为止,还没有人提到使用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]
如果使用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]
默认情况下Uint8Array
,Uint16Array
和Uint32Array
类将零作为其值,因此您不需要任何复杂的填充技术,只需执行以下操作:
var ary = new Uint8Array(10);
ary
默认情况下,数组的所有元素将为零。
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 Mlet a = new Float32Array(n)
(however is not typical array) - for it the fastest browser was Safari (for largen
>6x faster than Chrome, >9x faster than firefox) - 对于典型的数组,首选解决方案是A
let a = Array(n).fill(0)
(快速和短代码)
您可以在此处对机器进行测试。
I just use :