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


当前回答

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

其他回答

您可以检查索引是否存在,以便向其追加+1。

这样你就不需要一个填零的数组了。

例子:

var current_year = new Date().getFullYear();
var ages_array = new Array();

for (var i in data) {
    if(data[i]['BirthDate'] != null && data[i]['BirthDate'] != '0000-00-00'){

        var birth = new Date(data[i]['BirthDate']);
        var birth_year = birth.getFullYear();
        var age = current_year - birth_year;

        if(ages_array[age] == null){
            ages_array[age] = 1;
        }else{
            ages_array[age] += 1;
        }

    }
}

console.log(ages_array);

最快的方法是使用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']

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

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

ES6引入了Array.prototype.fill。它可以这样使用:

new Array(len).fill(0);

不确定它是否很快,但我喜欢它,因为它很短,很自我描述。

它仍然不在IE中(检查兼容性),但有一个polyfill可用。

我没有反对:

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

Zertosh建议,但在一个新的ES6阵列扩展中,您可以使用fill方法在本地执行此操作。现在IE edge、Chrome和FF都支持它,但请查看兼容性表

new Array(3).fill(0)将为您提供[0,0,0]。您可以用任何值填充数组,如new array(5).fill('abc')(甚至对象和其他数组)。

除此之外,您还可以使用填充修改以前的阵列:

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

这给了你:[1,2,3,9,9,6]