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


当前回答

我知道我在某个地方有这个原型:)

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's 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)。

其他回答

我知道这不是问题的目的,但这里有一个开箱即用的想法。为什么?我的CSci教授指出,用零来“净化”数据并没有什么神奇之处。因此,最有效的方法是根本不做!只有当数据需要为零作为初始条件(如某些求和)时才这样做——这通常不是大多数应用程序的情况。

我只使用:

var arr = [10];
for (var i=0; i<=arr.length;arr[i] = i, i++);

这里最快的是

(arr = []).length = len; arr.fill(0);

在答案中没有看到这种方法,所以这里是:

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

结果,您将得到长度为200的零值数组:

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

我不确定这段代码的性能,但如果您将它用于相对较小的阵列,这应该不是问题。

如果使用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]