在JavaScript中创建任意长度的零填充数组最有效的方法是什么?
当前回答
最快的方法是使用forEach=)
(我们保持IE<9的向后兼容性)
var fillArray = Array.prototype.forEach
? function(arr, n) {
arr.forEach(function(_, index) { arr[index] = n; });
return arr;
}
: function(arr, n) {
var len = arr.length;
arr.length = 0;
while(len--) arr.push(n);
return arr;
};
// test
fillArray([1,2,3], 'X'); // => ['X', 'X', 'X']
其他回答
这里最快的是
(arr = []).length = len; arr.fill(0);
简言之
最快的解决方案:
let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
最短(方便)的解决方案(小阵列慢3倍,大阵列慢一点(Firefox上最慢))
Array(n).fill(0)
细节
今天2020.06.09我在浏览器Chrome 83.0、Firefox 77.0和Safari 13.1上对macOS High Sierra 10.13.6进行测试。我测试了两个测试用例的所选解决方案
小数组-有10个元素-您可以在这里执行测试大阵列-具有1M个元素-您可以在这里执行测试
结论
基于新Array(n)+for(n)的解决方案是小型阵列和大型阵列的最快解决方案(Chrome除外,但仍非常快),建议作为快速跨浏览器解决方案基于新Float32Array(n)(I)的解决方案返回非典型数组(例如,您不能在其上调用push(..)),因此我不会将其结果与其他解决方案进行比较-但是,对于所有浏览器上的大型数组,此解决方案的速度比其他解决方案快10-20倍基于for(L,M,N,O)的解决方案对于小型阵列来说是快速的基于填充(B,C)的解决方案在Chrome和Safari上速度很快,但在Firefox上对于大型阵列的速度却慢得惊人。它们对于小型阵列来说是中速的基于Array.apply(P)的解决方案为大型阵列抛出错误函数P(n){return Array.apply(null,Array(n)).map(Number.pr原型.valueOf,0);}尝试{P(1000000);}捕获(e){console.error(e.message);}
代码和示例
以下代码显示了测量中使用的解决方案
函数A(n){return[…new Array(n)].fill(0);}函数B(n){返回新数组(n).fill(0);}函数C(n){return数组(n).fill(0);}函数D(n){return Array.from({length:n},()=>0);}函数E(n){return[…new Array(n)].map(x=>0);}//类型为的数组函数F(n){return Array.from(新Int32Array(n));}函数G(n){return Array.from(new Float32Array(n));}函数H(n){return Array.from(new Float64Array(n));//需要比float32多2倍的内存}函数I(n){返回新的Float32Array(n);//这不是典型的阵列}函数J(n){return[].slice.apply(new Float32Array(n));}//基于函数K(n){设a=[];a.长度=n;设i=0;而(i<n){a[i]=0;i++;}返回a;}函数L(n){设a=[];对于(设i=0;i<n;i++)a[i]=0;返回a;}函数M(n){设a=[];对于(设i=0;i<n;i++)a.push(0);返回a;}函数N(N){设a=新数组(n);对于(设i=0;i<n;++i)a[i]=0;返回a;}函数O(n){设a=新数组(n);对于(设i=n;i-;)a[i]=0;返回a;}//其他函数P(n){return Array.apply(null,Array(n)).map(Number.pr原型.valueOf,0);}函数Q(n){return“0”.repeat(n).split(“”).map(parseFloat);}函数R(n){返回新数组(n+1).join(“0”).split(“”).map(parseFloat)}// ---------//测试// ---------[A、B、C、D、E、F、G、H、I、J、K、L、M、N、O、P、Q、R]。对于每个(F=>{设a=f(10);console.log(`${f.name}长度=${a.length},arr[0]=${a[0]},arr[9]=${a[9]}`)});此代码段仅显示使用过的代码
Chrome的示例结果:
在答案中没有看到这种方法,所以这里是:
"0".repeat( 200 ).split("").map( parseFloat )
结果,您将得到长度为200的零值数组:
[ 0, 0, 0, 0, ... 0 ]
我不确定这段代码的性能,但如果您将它用于相对较小的阵列,这应该不是问题。
var str = "0000000...0000";
var arr = str.split("");
表达式中的用法:arr[i]*1;
编辑:如果arr应该在整数表达式中使用,那么请不要介意字符值“0”。您只需按如下方式使用它:a=a*arr[i](假设a具有整数值)。
其他人似乎缺少的是预先设置数组的长度,这样解释器就不会不断改变数组的大小。
我的简单一行代码是Array.protocol.slice.apply(newUint8Array(长度))
但是,如果我要创建一个函数来快速执行,而不需要一些复杂的变通方法,我可能会编写一个这样的函数:
var filledArray = function(value, l) {
var i = 0, a = []; a.length = l;
while(i<l) a[i++] = value;
return a;
}