Most efficient way to create a zero filled JavaScript array?

前端 未结 30 1190
花落未央
花落未央 2020-11-22 05:58

What is the most efficient way to create an arbitrary length zero filled array in JavaScript?

相关标签:
30条回答
  • 2020-11-22 06:22

    using object notation

    var x = [];
    

    zero filled? like...

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

    filled with 'undefined'...

    var x = new Array(7);
    

    obj notation with zeros

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

    As a side note, if you modify Array's prototype, both

    var x = new Array();
    

    and

    var y = [];
    

    will have those prototype modifications

    At any rate, I wouldn't be overly concerned with the efficiency or speed of this operation, there are plenty of other things that you will likely be doing that are far more wasteful and expensive than instanciating an array of arbitrary length containing zeros.

    0 讨论(0)
  • 2020-11-22 06:23

    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));
    
    0 讨论(0)
  • 2020-11-22 06:23

    What about new Array(51).join('0').split('')?

    0 讨论(0)
  • 2020-11-22 06:27

    I was testing out the great answer by T.J. Crowder, and came up with a recursive merge based on the concat solution that outperforms any in his tests in Chrome (i didn't test other browsers).

    function makeRec(len, acc) {
        if (acc == null) acc = [];
        if (len <= 1) return acc;
        var b = makeRec(len >> 1, [0]);
        b = b.concat(b);
        if (len & 1) b = b.concat([0]);
        return b;
    },
    

    call the method with makeRec(29).

    0 讨论(0)
  • 2020-11-22 06:28

    I knew I had this proto'd somewhere :)

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

    Edit: tests

    In response to Joshua and others methods I ran my own benchmarking, and I'm seeing completely different results to those reported.

    Here's what I tested:

    //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();
    

    Results:

    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
    

    So by my reckoning push is indeed slower generally but performs better with longer arrays in FF but worse in IE which just sucks in general (quel surprise).

    0 讨论(0)
  • 2020-11-22 06:29

    Anonymous function:

    (function(n) { while(n-- && this.push(0)); return this; }).call([], 5);
    // => [0, 0, 0, 0, 0]
    

    A bit shorter with for-loop:

    (function(n) { for(;n--;this.push(0)); return this; }).call([], 5);
    // => [0, 0, 0, 0, 0]
    

    Works with any Object, just change what's inside this.push().

    You can even save the function:

    function fill(size, content) {
      for(;size--;this.push(content));
      return this;
    }
    

    Call it using:

    var helloArray = fill.call([], 5, 'hello');
    // => ['hello', 'hello', 'hello', 'hello', 'hello']
    

    Adding elements to an already existing array:

    var helloWorldArray = fill.call(helloArray, 5, 'world');
    // => ['hello', 'hello', 'hello', 'hello', 'hello', 'world', 'world', 'world', 'world', 'world']
    

    Performance: http://jsperf.com/zero-filled-array-creation/25

    0 讨论(0)
提交回复
热议问题