Most efficient way to create a zero filled JavaScript array?
Asked Answered
A

46

870

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

Argenteuil answered 18/8, 2009 at 18:11 Comment(12)
Some actual data on this: jsperf.com/zeroarrayjsLavabo
ES6 fill allows to do this natively.Crimple
arr = new Array(length+1).joint(character).split('');Kursk
UPDATE 2016: Another custom benchmark here: jsfiddle.net/basickarl/md5z0LqqPak
let i = 0; Array.from(Array(10), ()=>i++);Cyanamide
Using typed arrays might be a good option when working with very large lookup tables for example. Speed comparision of typed array initialization: jsperf.com/new-int32array-vs-array-fillRoofing
For your information, Here is a benchmark between .fill() and for-loop.Homothermal
What do you mean by "most efficient"? Fewest CPU cycles? Lowest memory usage? Most compact source code?Jardine
I know this isn't the purpose of the question, but here's an out-of-the-box idea. Why? My CSci professor noted that there is nothing magical about 'cleansing' data with zero. So the most efficient way is to NOT do it at all! Only do it if the data needs to be always zero -- which is usually NOT the case.Humpbacked
This question might have the worst answers on stack overflow. The question is which method is the most efficient. 85% of the answer don't even attempt to answer the question, they just list a method which is not the question. Even the few that do try to list benchmarks all fail or have bad/incorrect answers.Forgo
Answer as of June 2020 see jsperf.com/fill-to-const-value/1Forgo
let arr = new Array(10).fill(0)Contestant
G
924

ES6 introduces Array.prototype.fill. It can be used like this:

new Array(len).fill(0);

Not sure if it's fast, but I like it because it's short and self-describing.

It's still not in IE (check compatibility), but there's a polyfill available.

Glynisglynn answered 27/4, 2014 at 17:30 Comment(13)
Polyfill available here developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Scarborough
This isn't working with babel nor even enabling the experimental JavaScript flag on Chrome. Any idea(s) why?Imponderabilia
@ConAntonakos It should work on Chrome 45, or Chrome 36 with “Enable Experimental JavaScript”Glynisglynn
fill is fast. new Array(len) is painfully slow. (arr = []).length = len; arr.fill(0); is about the fastest solution ive seen anywhere... or at least tiedRhododendron
@PimpTrizkit arr = Array(n) and (arr = []).length = n behave identically according to the spec. In some implementations one could be faster, but I don't think there is a big difference.Glynisglynn
Yes, they do, hence why I suggested as an alternative. And in most cases when I use it in final stress testing... the (arr = []).length = len; arr.fill(0); is much faster. It does seem tho, certain sizes in certain environments it is faster to use new Array. But after all the design and speed testing is done, that is so rare for me.Rhododendron
@PimpTrizkit I tested it with Firefox Nightly with arrays of 1e3 zeros and your code was twice as slow. Even if the test weren't much reliable, I don't think new Array(len) is painfully slow.Glynisglynn
Well, I started testing it with multi dimensional arrays and it seemed to greatly speed up my test cases. Having just now done some more testing on FF41 and Chrome45.0.2454.99 m. Yes, I guess I really needed more space to explain myself. Most of my testing was bias I will admit. But, check this out. Predefine a var and using just this line (arr = []).length = 1000; against arr = new Array(1000); speed test it in both Chrome and FF... the new is terribly slow. Now, for array lengths smaller.. say < 50 or there abouts... then new Array() does seem to perform better. But..Rhododendron
... I will admit I missed this part ... when I add the second line to the test... arr.fill(0) ... everything sorta changes. Now, using new Array() is faster in most cases except when you get to array sizes > 100000... Then you can start to see the speed increase again. But if you don't actually have to prefill it with zeros and can use standard falisy of empty arrays. Then (arr = []).length = x is crazy fast in my test cases most of the time.Rhododendron
Note that to iterate over the array (e.g. map or forEach) the values must be set, otherwise it will skip those indexes. The values you set can be whatever you want – even undefined. Example: try new Array(5).forEach(val => console.log('hi')); vs new Array(5).fill(undefined).forEach(val => console.log('hi'));.Sula
I’m seeing fill() being quite a bit slower than a for loop when the array gets really big: jsperf.com/zero-filling-large-arrays And no significant difference between new Array(n) and a = []; a.length = nBeauty
Just ran some tests on Chrome 77 and a simple loop with push() ran twice faster than fill().Supporting
this is crazy blooddy working :DTeniafuge
R
412

Although this is an old thread, I wanted to add my 2 cents to it. Not sure how slow/fast this is, but it's a quick one liner. Here is what I do:

If I want to pre-fill with a number:

Array.apply(null, Array(5)).map(Number.prototype.valueOf,0);
// [0, 0, 0, 0, 0]

If I want to pre-fill with a string:

Array.apply(null, Array(3)).map(String.prototype.valueOf,"hi")
// ["hi", "hi", "hi"]

Other answers have suggested:

new Array(5+1).join('0').split('')
// ["0", "0", "0", "0", "0"]

but if you want 0 (the number) and not "0" (zero inside a string), you can do:

new Array(5+1).join('0').split('').map(parseFloat)
// [0, 0, 0, 0, 0]
Risibility answered 6/12, 2012 at 1:16 Comment(15)
Great answer! Can you please explain the trick with Array.apply(null, new Array(5)).map(...)? Cause simply doing (new Array(5)).map(...) won't work as the spec tellsAtwood
(btw, we don't really need the new) When you do Array(5) you're creating an object that kinda looks like this: { length: 5, __proto__: Array.prototype } - try console.dir( Array(5) ). Notice that it doesn't have any properties 0, 1, 2, etc. But when you apply that unto the Array constructor, it's like saying Array(undefined, undefined, undefined, undefined, undefined). And you get an object that kinda looks like { length: 5, 0: undefined, 1: undefined...}. map works on the properties 0,1, etc. which is why your example doesn't work, but when you use apply it does.Risibility
Thanks for the explanation! So null as constructor function execution context doesn't really matter there, it could as well be {} or []?Atwood
The first parameter for .apply is actually what you want the this to be. For these purposes the this doesn't matter - we only really care about the parameter spreading "feature" of .apply - so it can be any value. I like null because it's cheap, you probably don't want to use {} or [] since you'd be instantiating an object for no reason.Risibility
This is cool javascript syntax but it is very very slow if compared to a naive solution like makeWithCountUp(len) from T.J. Crowder answer.I got this from benchmarking it: Results: Length: 10000 Loops: 500 First map solution, average time: 7.576ms Count down, post-decrement, average time: 0.126ms Count up (normal), average time: 0.06ms Count down (for loop) and up (for filling), average time: 0.28ms Concat, average time: 0.282ms On Chrome.Cytogenetics
Also initialize with size + assign is much faster than push. See test case jsperf.com/zero-fill-2d-arrayPoliceman
@AlixAxel your link is broken. Maybe post an answer comparing speeds?Iodate
Can we use this method to create an array of nulls? I can use: Array.apply(null, new Array(size)).map(function() {return null;}) but wasn't sure if there was a better way than creating an inline functionIncubate
let's add new Array(5).fill(0); from ES2015 to this beautiful answerMastectomy
In Array.apply(null, Array(3)) you can also use Array.apply(null, { length: 3 }), which is still a tiny bit faster in FF (no difference in Chrome, tough): jsperf.com/array-apply-lengthMalamud
what about Array.apply(null, Array(5)).map(x=>0)? It's a little bit shorter!Wiseacre
@Risibility why is it that using just Array(5) doesn't have the properties 0,1,2 (enumerable indices)?Jessy
replacing Number.prototype.valueOf,0 with just function() {return 0} seems a bit faster.Disfrock
In ES6 you can use Array(...Array(5)) to create array of undefinedsLaurenelaurens
In Chrome 88.0.4324.190: Array.apply(null, Array(1000000)) VM3904:1 Uncaught RangeError: Maximum call stack size exceeded at <anonymous>:1:7Stagemanage
U
183

In short

Fastest solution:

let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;

Shortest (handy) solution (3x slower for small arrays, slightly slower for big (slowest on Firefox))

Array(n).fill(0)

Details

Today 2020.06.09 I perform tests on macOS High Sierra 10.13.6 on browsers Chrome 83.0, Firefox 77.0, and Safari 13.1. I test chosen solutions for two test cases

  • small array - with 10 elements - you can perform test HERE
  • big arrays - with 1M elements - you can perform test HERE

Conclusions

  • solution based on new Array(n)+for (N) is fastest solution for small arrays and big arrays (except Chrome but still very fast there) and it is recommended as fast cross-browser solution
  • solution based on new Float32Array(n) (I) returns non typical array (e.g. you cannot call push(..) on it) so I not compare its results with other solutions - however this solution is about 10-20x faster than other solutions for big arrays on all browsers
  • solutions based on for (L,M,N,O) are fast for small arrays
  • solutions based on fill (B,C) are fast on Chrome and Safari but surprisingly slowest on Firefox for big arrays. They are medium fast for small arrays
  • solution based on Array.apply (P) throws error for big arrays
    function P(n) {
      return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
    }
    
    try {
      P(1000000);
    } catch(e) { 
      console.error(e.message);
    }

enter image description here

Code and example

Below code presents solutions used in measurements

function A(n) {
  return [...new Array(n)].fill(0);
}

function B(n) {
  return new Array(n).fill(0);
}

function C(n) {
  return Array(n).fill(0);
}

function D(n) {
  return Array.from({length: n}, () => 0);
}

function E(n) {
  return [...new Array(n)].map(x => 0);
}

// arrays with type

function F(n) {
  return Array.from(new Int32Array(n));
}

function G(n) {
  return Array.from(new Float32Array(n));
}

function H(n) {
  return Array.from(new Float64Array(n)); // needs 2x more memory than float32
}

function I(n) {
  return new Float32Array(n); // this is not typical array
}

function J(n) {
  return [].slice.apply(new Float32Array(n));
}

// Based on for

function K(n) {
  let a = [];
  a.length = n;
  let i = 0;
  while (i < n) {
    a[i] = 0;
    i++;
  }
  return a;
}

function L(n) {
  let a=[]; for(let i=0; i<n; i++) a[i]=0;
  return a;
}

function M(n) {
  let a=[]; for(let i=0; i<n; i++) a.push(0);
  return a;
}

function N(n) {
  let a = new Array(n); for (let i=0; i<n; ++i) a[i] = 0;
  return a;
}

function O(n) {
  let a = new Array(n); for (let i=n; i--;) a[i] = 0;
  return a;
}

// other

function P(n) {
  return Array.apply(null, Array(n)).map(Number.prototype.valueOf,0);
}

function Q(n) {
  return "0".repeat( n ).split("").map( parseFloat );
}

function R(n) {
  return new Array(n+1).join('0').split('').map(parseFloat)
}

// ---------
// TEST
// ---------
[A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R].forEach(f => {
  let a = f(10); 
  console.log(`${f.name} length=${a.length}, arr[0]=${a[0]}, arr[9]=${a[9]}`)
});
This snippets only present used codes

Example results for Chrome:

enter image description here

Uppity answered 28/10, 2018 at 8:54 Comment(5)
Just ran some tests on Chrome 77 and a simple loop with push() is twice faster than fill()... I wonder what subtle side-effects of fill() prevent a more efficient implementation?Supporting
@EricGrange I update answer - at the bottom I update link to benchamrk with your proposition: case P let a=[]; for(i=n;i--;) a.push(0); - but it is 4x slower than fill(0) - so I will even not update the picture witch that case.Internecine
Nice measurements. Analysis: G is slow because of resizing the array at every iteration, and resizing means doing a new memory allocation. A,B,M fast because the sizing is done only once. +1Terpsichore
@Terpsichore I think you mean N instead of M?Devisee
for-loop (N) was only 1.835 faster than .fill (C) in Safari, and it's interesting to note that when I ran it now, 6 months later, the difference has gone down to only 1.456x. So for Safari, the fastest solution (N) is only 45% faster than the shortest and simplest version. Moral: Stick with the shortest and simplest versions (for most if not all cases). It saves expensive developer time, through being faster to read, easier to maintain, and also pays off more and more as time and CPU speeds increase, without extra maintenance.Reinke
C
134

Elegant way to fill an array with precomputed values

Here is another way to do it using ES6 that nobody has mentioned so far:

> Array.from(Array(3), () => 0)
< [0, 0, 0]

It works by passing a map function as the second parameter of Array.from.

In the example above, the first parameter allocates an array of 3 positions filled with the value undefined and then the lambda function maps each one of them to the value 0.

Although Array(len).fill(0) is shorter, it doesn't work if you need to fill the array by doing some computation first (I know the question didn't ask for it, but a lot of people end up here looking for this).

For instance, if you need an array with 10 random numbers:

> Array.from(Array(10), () => Math.floor(10 * Math.random()))
< [3, 6, 8, 1, 9, 3, 0, 6, 7, 1]

It's more concise (and elegant) than the equivalent:

const numbers = Array(10);
for (let i = 0; i < numbers.length; i++) {
    numbers[i] = Math.round(10 * Math.random());
}

This method can also be used to generate sequences of numbers by taking advantage of the index parameter provided in the callback:

> Array.from(Array(10), (d, i) => i)
< [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Bonus answer: fill an array using String repeat()

Since this answer is getting a good deal of attention, I also wanted to show this cool trick. Although not as useful as my main answer, will introduce the still not very known, but very useful String repeat() method. Here's the trick:

> "?".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]
Crossbones answered 22/5, 2016 at 17:17 Comment(5)
Lots of parlor tricks in that post, but hopefully none that will reach production code :)Supporting
Although the repeat trick is definitely not wanted in production, Array.from() is perfectly fine :-)Crossbones
Not really, Array.from() here is basically creating an array, iterating through it with map(), calling a function on each item to create a new array, then discarding the first array... For a small arrays this may be innocuous, for larger arrays, this is the kind of pattern that result in people calling browsers "memory hogs" :)Supporting
People dealing with large arrays should know better than this, definitely. For common apps, though, creating a regular-sized aux array (up to 10k elements) that will be immediately disposed is perfectly fine (takes the same amount of time as if you avoided the extra array creation - tested with latest Chrome). For cases like that, readability becomes more important than tiny performance optimizations. About the O(n) time, it's necessary if you need to compute something different for each element (the main subject of my answer). This discussion is very interesting, glad that you raised it!Crossbones
^ To clarify for future readers: the above comments imply that Array(N) pre-allocates N cells, which isn't necessarily true, otherwise Array(2**32 - 1) would be allocating more than all my RAM. Browser engines likely use various heuristics to determine whether or not to allocate in advance or use a sparse array. In any case, you can use Array.from({ length: N }, callback) instead.Wembley
C
64

The already mentioned ES 6 fill method takes care of this nicely. Most modern desktop browsers already support the required Array prototype methods as of today (Chromium, FF, Edge and Safari) [1]. You can look up details on MDN. A simple usage example is

a = new Array(10).fill(0);

Given the current browser support you should be cautious to use this unless you are sure your audience uses modern Desktop browsers.

Chime answered 9/1, 2016 at 13:3 Comment(4)
If you fill with a reference type it will be the same reference across all of them. new Array(10).fill(null).map(() => []) would be a succinct way to get around this (burned me initially haha)Attemper
UPDATE 2016: This method blows everything else out of the water, click here for benchmarks: jsfiddle.net/basickarl/md5z0LqqPak
this will work for arrays. a = Array(10).fill(null).map(() => { return []; });Spiegelman
@AndrewAnthonyGerst Terser: a = Array(10).fill(0).map( _ => [] );Manos
O
56

Note added August 2013, updated February 2015: The answer below from 2009 relates to JavaScript's generic Array type. It doesn't relate to the newer typed arrays defined in ES2015 [and available now in many browsers], like Int32Array and such. Also note that ES2015 adds a fill method to both Arrays and typed arrays, which is likely to be the most efficient way to fill them...

Also, it can make a big difference to some implementations how you create the array. Chrome's V8 engine, in particular, tries to use a highly-efficient, contiguous-memory array if it thinks it can, shifting to the object-based array only when necessary.


With most languages, it would be pre-allocate, then zero-fill, like this:

function newFilledArray(len, val) {
    var rv = new Array(len);
    while (--len >= 0) {
        rv[len] = val;
    }
    return rv;
}

But, JavaScript arrays aren't really arrays, they're key/value maps just like all other JavaScript objects, so there's no "pre-allocate" to do (setting the length doesn't allocate that many slots to fill), nor is there any reason to believe that the benefit of counting down to zero (which is just to make the comparison in the loop fast) isn't outweighed by adding the keys in reverse order when the implementation may well have optimized their handling of the keys related to arrays on the theory you'll generally do them in order.

In fact, Matthew Crumley pointed out that counting down is markedly slower on Firefox than counting up, a result I can confirm — it's the array part of it (looping down to zero is still faster than looping up to a limit in a var). Apparently adding the elements to the array in reverse order is a slow op on Firefox. In fact, the results vary quite a bit by JavaScript implementation (which isn't all that surprising). Here's a quick and dirty test page (below) for browser implementations (very dirty, doesn't yield during tests, so provides minimal feedback and will run afoul of script time limits). I recommend refreshing between tests; FF (at least) slows down on repeated tests if you don't.

The fairly complicated version that uses Array#concat is faster than a straight init on FF as of somewhere between 1,000 and 2,000 element arrays. On Chrome's V8 engine, though, straight init wins out every time...

Here's a test:

const tests = [
    {
        name:   "downpre",
        total:  0,
        desc:   "Count down, pre-decrement",
        func:   makeWithCountDownPre
    },
    {
        name:   "downpost",
        total:  0,
        desc:   "Count down, post-decrement",
        func:   makeWithCountDownPost
    },
    {
        name:   "up",
        total:  0,
        desc:   "Count up (normal)",
        func:   makeWithCountUp
    },
    {
        name:   "downandup",
        total:  0,
        desc:   "Count down (for loop) and up (for filling)",
        func:   makeWithCountDownArrayUp
    },
    {
        name:   "concat",
        total:  0,
        desc:   "Concat",
        func:   makeWithConcat
    }
];

const q = sel => document.querySelector(sel);

let markup = "";
for (const {name, desc} of tests) {
    markup += `
        <div><input type="checkbox" id="chk_${name}" checked>
        <label for="chk_${name}">${desc}</label></div>`;
}
q("#checkboxes").innerHTML = markup;
q("#btnTest").addEventListener("click", btnTestClick);

function btnTestClick() {
    // Clear log
    q("#log").innerHTML = "Testing...";

    // Show running
    q("#btnTest").disabled = true;

    // Run after a pause while the browser updates display
    setTimeout(btnTestClickPart2, 0);
}

function btnTestClickPart2() {
    try {
        runTests();
    } catch (e) {
        log(`Exception: ${e.message}`);
    }

    // Re-enable the button
    q("#btnTest").disabled = false;
}

function getNumField(name) {
    const val = q("#" + name).value.trim();
    const num = /^\d+$/.test(val) ? parseInt(val) : NaN;
    if (isNaN(num) || num <= 0) {
        throw new Error(`Invalid ${name} value ${JSON.stringify(val)}`);
    }
    return num;
}

function runTests() {
    try {
        // Clear log
        q("#log").innerHTML = "";

        const runCount = getNumField("loops");
        const length = getNumField("length");

        // Do it (we run runCount + 1 times, first time is a warm up)
        for (let counter = 0; counter <= runCount; ++counter) {
            for (const test of tests) {
                if (q("#chk_" + test.name).checked) {
                    const start = Date.now();
                    const a = test.func(length);
                    const time = Date.now() - start;
                    if (counter == 0) {
                        // Don't count (warm up), but do check the algorithm works
                        const invalid = validateResult(a, length);
                        if (invalid) {
                            log(`<span class=error>FAILURE</span> with test ${test.name}: ${invalid}`);
                            return;
                        }
                    } else {
                        // Count this one
                        log(`#${counter}: ${test.desc}: ${time}ms`);
                        test.total += time;
                    }
                }
            }
        }

        for (const test of tests) {
            if (q("#chk_" + test.name).checked) {
                test.avg = test.total / runCount;
                if (typeof lowest != "number" || lowest > test.avg) {
                    lowest = test.avg;
                }
            }
        }

        let results =
            "<p>Results:" +
            "<br>Length: " + length +
            "<br>Loops: " + runCount +
            "</p>";
        for (const test of tests) {
            if (q("#chk_" + test.name).checked) {
                results +=
                    `<p ${lowest == test.avg ? " class=winner" : ""}>${test.desc}, average time: ${test.avg}ms</p>`;
            }
        }
        results += "<hr>";
        q("#log").insertAdjacentHTML("afterbegin", results);
    } catch (e) {
        log(e.message);
        return;
    }
}

function validateResult(a, length) {
    if (a.length != length) {
        return "Length is wrong";
    }
    for (let n = length - 1; n >= 0; --n) {
        if (a[n] != 0) {
            return "Index " + n + " is not zero";
        }
    }
    return undefined;
}

function makeWithCountDownPre(len) {
    const a = new Array(len);
    while (--len >= 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountDownPost(len) {
    const a = new Array(len);
    while (len-- > 0) {
        a[len] = 0;
    }
    return a;
}

function makeWithCountUp(len) {
    const a = new Array(len);
    for (let i = 0; i < len; ++i) {
        a[i] = 0;
    }
    return a;
}

function makeWithCountDownArrayUp(len) {
    const a = new Array(len);
    let i = 0;
    while (--len >= 0) {
        a[i++] = 0;
    }
    return a;
}

function makeWithConcat(len) {
    if (len == 0) {
        return [];
    }
    let a = [0];
    let currlen = 1;
    while (currlen < len) {
        const rem = len - currlen;
        if (rem < currlen) {
            a = a.concat(a.slice(0, rem));
        } else {
            a = a.concat(a);
        }
        currlen = a.length;
    }
    return a;
}

function log(msg) {
    const p = document.createElement("p");
    p.textContent = msg;
    q("#log").appendChild(p);
}
body {
    font-family: sans-serif;
}
#log p {
    margin: 0;
    padding: 0;
}
.error {
    color: red;
}
.winner {
    color: green;
}
<div>
<label for='txtLength'>Length:</label><input type='text' id='length' value='1000'>
<br><label for='txtLoops'>Loops:</label><input type='text' id='loops' value='100000'>
<div id='checkboxes'></div>
<br><input type='button' id='btnTest' value='Test'>
<hr>
<div id='log'></div>
</div>
Ostracon answered 18/8, 2009 at 18:29 Comment(12)
Not sure that backwards filling would matter here, given you are only accessing elements (not deleting them) and you've already pre-allocated. Am I wrong?Bakehouse
the point of the backwards fill is not particularly to do with the array, it's to do with the escape condition for the while - the falsey 0 terminates the loop very efficientlyPhoenix
(though I've just noticed this code doesn't actually make use of that)Phoenix
@annakata, you can't make use of that here, because 0 is a valid index.Bakehouse
@triptych: not true, all it takes is the right order - see my postPhoenix
@Triptych & annakata: Zeroes aside, comparing to a constant is likely to be more efficient than to a variable, although with a JIT-enabled compiler it may well not matter. And depending on the JIT it might make use of the falsey compare and just do a final store outside the loop. The point is that it isn't going to be less efficient than filling forward and comparing to a variable.Ostracon
(or kangax's - same thing there)Phoenix
@TJ: comparing to a constant is likely to achieve an infinite loop - something must change in the condition :)Phoenix
@annakata: Ha, ha. Comparing a variable to a constant.Ostracon
Counting down in Firefox is much slower than counting up. I have no idea why, but in my tests, it was 10-15 times slower.Grandeur
@Matthew: Nice one, just proves you should always test your assumptions. I've replicated your result and updated the answer.Ostracon
@nickf: Which method? There are five in this answer.Ostracon
L
41

If you use ES6, you can use Array.from() like this:

Array.from({ length: 3 }, () => 0);
//[0, 0, 0]

Has the same result as

Array.from({ length: 3 }).map(() => 0)
//[0, 0, 0]

Because

Array.from({ length: 3 })
//[undefined, undefined, undefined]
Lunkhead answered 16/7, 2016 at 12:20 Comment(0)
P
36

By default Uint8Array, Uint16Array and Uint32Array classes keep zeros as its values, so you don't need any complex filling techniques, just do:

var ary = new Uint8Array(10);

all elements of array ary will be zeros by default.

Pentangular answered 5/3, 2014 at 21:30 Comment(4)
This is nice but mind note this cannot be treated the same as a normal array, e.g. Array.isArray(ary) is false. The length is also read-only so you cannot push new items to it as with ary.pushAirt
Fwiw all typed arrays keep 0 as their default value.Beast
@MusikAnimal, Array.from(new Uint8Array(10)) will provide a normal array.Omdurman
@TomasLangkaas: Yes, but another answer shows that that's about 5x slower than Array(n).fill(0) in Chrome if what you really need is a JS Array. If you can use a TypedArray, this is much faster even than .fill(0), though, especially if you can use the default initializer value of 0. There doesn't seem to be a constructor that takes a fill-value and length, the way C++ std::vector has. It seems for any non-zero value you have to construct a zeroed TypedArray and then fill it. :/Shores
S
27
function makeArrayOf(value, length) {
  var arr = [], i = length;
  while (i--) {
    arr[i] = value;
  }
  return arr;
}

makeArrayOf(0, 5); // [0, 0, 0, 0, 0]

makeArrayOf('x', 3); // ['x', 'x', 'x']

Note that while is usually more efficient than for-in, forEach, etc.

Stenosis answered 18/8, 2009 at 18:22 Comment(2)
Isn't the i local variable extraneous? length is passed by value so you should be able to decrement it directly.Fierce
Although this looks great at first, unfortunately it's very slow to assign values at an arbitrary point in an arary (e.g. arr[i] = value). It's much faster to loop through from beginning to end and use arr.push(value). It's annoying, because I prefer your method.Evangelineevangelism
D
26

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.

Diazine answered 18/8, 2009 at 18:13 Comment(6)
Err... there are no nulls in this array - var x = new Array(7);Stenosis
Actually, the array doesn't get filled with anything with new Array(n), not even 'undefined's, it simply sets the arrays length value to n. You can check this by calling (new Array(1)).forEach(...). forEach never executes, unlike if you call it on [undefined].Me
new Array(7) does not create an array "filled with undefined". It creates an empty array with length 7.Canady
You might want to reconsider parts of your answer as what @Canady is saying is critical (if what you were saying is true, mapping would have been much easier)Tver
These days you could do (new Array(10)).fill(0).Heiduc
you don't need the keyword new. Array(10).fill(0) is equivalent and shorter. For proof that Array(10) is equivalent to new Array(10), see https://mcmap.net/q/20993/-array-vs-new-arrayTiptop
G
21

I've tested all combinations of pre-allocating/not pre-allocating, counting up/down, and for/while loops in IE 6/7/8, Firefox 3.5, Chrome, and Opera.

The functions below was consistently the fastest or extremely close in Firefox, Chrome, and IE8, and not much slower than the fastest in Opera and IE 6. It's also the simplest and clearest in my opinion. I've found several browsers where the while loop version is slightly faster, so I'm including it too for reference.

function newFilledArray(length, val) {
    var array = [];
    for (var i = 0; i < length; i++) {
        array[i] = val;
    }
    return array;
}

or

function newFilledArray(length, val) {
    var array = [];
    var i = 0;
    while (i < length) {
        array[i++] = val;
    }
    return array;
}
Grandeur answered 18/8, 2009 at 21:39 Comment(5)
You could also throw the var array = [] declaration into the first part of the for loop actually, separated by only a comma.Hydrophobic
I like that suggestion by damianb, but remember to put the assignment and comma before the incrementation! `for (var i = 0; i < length; array[i] = val, i++);Cerelly
Do what everyone else is missing to your second one, and set the length of the array to the length value already given so that it's not constantly changing. Brought a 1 million length array of zero's from 40ms to 8 on my machine.Vitalis
I seem to get a 10-15% speed increase when I refactor this solution into a one liner. for (i = 0, array = []; i < length; ++i) array[i] = val;.. Fewer blocks? ... anyhow, also... if I set the array.length of the new array to the length.. i seem to get another 10%-15% speed increase in FF... in Chrome, it seems to double the speed -> var i, array = []; array.length = length; while(i < length) array[i++] = val; (was still faster if I left it as a for loop... but the init is no longer needed, so the while is seemly faster on this version)Rhododendron
I will also note that in my testing. In a decent number of my test cases, the final version above seems to perform 3x to well over 10x faster... Im not so sure why... (different array sizes tested between chrome and FF)Rhododendron
I
18

ES6 solution:

[...new Array(5)].map(x => 0); // [0, 0, 0, 0, 0]
Incorporeity answered 7/12, 2017 at 17:52 Comment(1)
Awesome! Glean and simple solutionGuffey
A
18

const arr = Array.from({ length: 10 }).fill(0);
console.log(arr)
Arlindaarline answered 30/10, 2019 at 12:18 Comment(0)
L
15

If you need to create many zero filled arrays of different lengths during the execution of your code, the fastest way I've found to achieve this is to create a zero array once, using one of the methods mentioned on this topic, of a length which you know will never be exceeded, and then slice that array as necessary.

For example (using the function from the chosen answer above to initialize the array), create a zero filled array of length maxLength, as a variable visible to the code that needs zero arrays:

var zero = newFilledArray(maxLength, 0);

Now slice this array everytime you need a zero filled array of length requiredLength < maxLength:

zero.slice(0, requiredLength);

I was creating zero filled arrays thousands of times during execution of my code, this speeded up the process tremendously.

Leatri answered 25/1, 2012 at 13:4 Comment(0)
V
15
function zeroFilledArray(size) {
    return new Array(size + 1).join('0').split('');
}
Vassili answered 3/3, 2012 at 17:4 Comment(2)
You might also use new Array(size+1).join("x").split("x").map(function() { return 0; }) to get actual numbersOlivia
@Olivia Or just new Array(size+1).join('0').split('').map(Number)Pearl
B
12

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));
Boneset answered 14/4, 2014 at 14:17 Comment(3)
So glad you added this answer, as I use underscore, and I knew there was something for this... but hadn't been able to find it yet. I just wish I could create arrays of objects using thisArsenide
@Arsenide _.range(0, length -1, 0).map(Object.new), I think.Boneset
Should be _.range(0, length, 0), I believe. Lodash is exclusive of end valueHeckelphone
C
12

I have nothing against:

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

suggested by Zertosh, but in a new ES6 array extensions allow you to do this natively with fill method. Now IE edge, Chrome and FF supports it, but check the compatibility table

new Array(3).fill(0) will give you [0, 0, 0]. You can fill the array with any value like new Array(5).fill('abc') (even objects and other arrays).

On top of that you can modify previous arrays with fill:

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

which gives you: [1, 2, 3, 9, 9, 6]

Crimple answered 26/9, 2015 at 22:25 Comment(0)
M
11

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)]);
Mensuration answered 28/5, 2019 at 13:15 Comment(0)
S
10

The way I usually do it (and is amazing fast) is using Uint8Array. For example, creating a zero filled vector of 1M elements:

  var zeroFilled = [].slice.apply(new Uint8Array(1000000))

I'm a Linux user and always have worked for me, but once a friend using a Mac had some non-zero elements. I thought his machine was malfunctioning, but still here's the safest way we found to fix it:

  var zeroFilled = [].slice.apply(new Uint8Array(new Array(1000000)) 

Edited

Chrome 25.0.1364.160

  1. Frederik Gottlieb - 6.43
  2. Sam Barnum - 4.83
  3. Eli - 3.68
  4. Joshua 2.91
  5. Mathew Crumley - 2.67
  6. bduran - 2.55
  7. Allen Rice - 2.11
  8. kangax - 0.68
  9. Tj. Crowder - 0.67
  10. zertosh - ERROR

Firefox 20.0

  1. Allen Rice - 1.85
  2. Joshua - 1.82
  3. Mathew Crumley - 1.79
  4. bduran - 1.37
  5. Frederik Gottlieb - 0.67
  6. Sam Barnum - 0.63
  7. Eli - 0.59
  8. kagax - 0.13
  9. Tj. Crowder - 0.13
  10. zertosh - ERROR

Missing the most important test (at least for me): the Node.js one. I suspect it close to Chrome benchmark.

Seamount answered 27/2, 2014 at 10:9 Comment(3)
This is the most efficient way for my fingers, and for my eyes. But it's very very slow for Chrome (accord to that jsperf. 99% slower).Alkoran
I wonder if the problem on your friend's Mac was related to: stackoverflow.com/questions/39129200/… or maybe Array.slice wasn't handling the UInt8Array and leaking uninitialised memory? (a security issue!).Dezhnev
@Dezhnev Good catch! If I remember it well we were using Node.js 0.6 or 0.8. We thought about some kind of leaking but we could not reproduce it with the production stack so we just decided to ignore it.Seamount
C
8

As of ECMAScript2016, there is one clear choice for large arrays.

Since this answer still shows up near the top on google searches, here's an answer for 2017.

Here's a current jsbench with a few dozen popular methods, including many proposed up to now on this question. If you find a better method please add, fork and share.

I want to note that there is no true most efficient way to create an arbitrary length zero filled array. You can optimize for speed, or for clarity and maintainability - either can be considered the more efficient choice depending on the needs of the project.

When optimizing for speed, you want to: create the array using literal syntax; set the length, initialize iterating variable, and iterate through the array using a while loop. Here's an example.

const arr = [];
arr.length = 120000;
let i = 0;
while (i < 120000) {
  arr[i] = 0;
  i++;
}

Another possible implementation would be:

(arr = []).length = n;
let i = 0;
while (i < n) {
    arr[i] = 0;
    i++;
}

But I strongly discourage using this second implantation in practice as it's less clear and doesn't allow you to maintain block scoping on your array variable.

These are significantly faster than filling with a for loop, and about 90% faster than the standard method of

const arr = Array(n).fill(0);

But this fill method is still the most efficient choice for smaller arrays due to it's clarity, conciseness and maintainability. The performance difference likely won't kill you unless you're making a lot of arrays with lengths on the order of thousands or more.

A few other important notes. Most style guides recommend you no longer use varwithout a very special reason when using ES6 or later. Use const for variables that won't be redefined and let for variables that will. The MDN and Airbnb's Style Guide are great places to go for more information on best practices. The questions wasn't about syntax, but it's important that people new to JS know about these new standards when searching through these reams of old and new answers.

Caesium answered 2/3, 2017 at 3:52 Comment(0)
K
7

Didn't see this method in answers, so here it is:

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

In result you will get zero-valued array of length 200:

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

I'm not sure about the performance of this code, but it shouldn't be an issue if you use it for relatively small arrays.

Keewatin answered 7/12, 2016 at 15:41 Comment(1)
Neither the fastest nor the shortest but a nice contribution to the diversity of solutions.Fishmonger
O
6

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

Ornamental answered 26/1, 2012 at 22:55 Comment(3)
then .map(function(a){return +a}) ?Chancellorsville
as for 2020, what about new Array(51).fill(0)? It gives exact the same output.Duchess
"0".repeat(100000000).split(''); significantly faster than all others.Cabanatuan
P
4

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

Phoenix answered 18/8, 2009 at 21:5 Comment(2)
I've just tested this out: the second method (b = []...) is 10-15% faster than the first, but it's more than 10 times slower than Joshua's answer.Cryptozoic
I know this is an ancient post. But maybe it is still of interest to others (like me). Therefore I would like to suggest an adition to the prototype function: include an else {this.length=n;} after the this.length-check. This will shorten an already existing array if necessary when re-init-ialising it to a different length n.Backandforth
S
4

My fastest function would be:

function newFilledArray(len, val) {
    var a = [];
    while(len--){
        a.push(val);
    }
    return a;
}

var st = (new Date()).getTime();
newFilledArray(1000000, 0)
console.log((new Date()).getTime() - st); // returned 63, 65, 62 milliseconds

Using the native push and shift to add items to the array is much faster (about 10 times) than declaring the array scope and referencing each item to set it's value.

fyi: I consistently get faster times with the first loop, which is counting down, when running this in firebug (firefox extension).

var a = [];
var len = 1000000;
var st = (new Date()).getTime();
while(len){
    a.push(0);
    len -= 1;
}
console.log((new Date()).getTime() - st); // returned 863, 894, 875 milliseconds
st = (new Date()).getTime();
len = 1000000;
a = [];
for(var i = 0; i < len; i++){
    a.push(0);
}
console.log((new Date()).getTime() - st); // returned 1155, 1179, 1163 milliseconds

I'm interested to know what T.J. Crowder makes of that ? :-)

Serle answered 21/8, 2009 at 8:6 Comment(2)
You can make it faster by changing it to while (len--).. took my processing times from about 60ms to about 54msCryptozoic
Matthew Crumbly's answer still actually beats this (30ms)!Cryptozoic
S
4

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('');
}
Shrift answered 22/3, 2013 at 1:19 Comment(1)
Ok, wild. That is WAY faster than using new Array(len). BUT! I am seeing in Chrome that the subsequent reads to that data take substantially longer. Here are some timestamps to show what I mean: (Using new Array(len)) 0.365: Making Array 4.526: Executing Convolution 10.75: Convolution Complete (Using concat) 0.339: Making Array 0.591: Executing Convolution //OMG, WAY faster 18.056: Convolution CompleteRejoin
S
4

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

Shellishellie answered 4/7, 2013 at 9:6 Comment(0)
N
4

It might be worth pointing out, that Array.prototype.fill had been added as part of the ECMAScript 6 (Harmony) proposal. I would rather go with the polyfill written below, before considering other options mentioned on the thread.

if (!Array.prototype.fill) {
  Array.prototype.fill = function(value) {

    // Steps 1-2.
    if (this == null) {
      throw new TypeError('this is null or not defined');
    }

    var O = Object(this);

    // Steps 3-5.
    var len = O.length >>> 0;

    // Steps 6-7.
    var start = arguments[1];
    var relativeStart = start >> 0;

    // Step 8.
    var k = relativeStart < 0 ?
      Math.max(len + relativeStart, 0) :
      Math.min(relativeStart, len);

    // Steps 9-10.
    var end = arguments[2];
    var relativeEnd = end === undefined ?
      len : end >> 0;

    // Step 11.
    var final = relativeEnd < 0 ?
      Math.max(len + relativeEnd, 0) :
      Math.min(relativeEnd, len);

    // Step 12.
    while (k < final) {
      O[k] = value;
      k++;
    }

    // Step 13.
    return O;
  };
}
Nympho answered 25/2, 2015 at 10:11 Comment(0)
A
4

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;
Affirmatory answered 23/1, 2016 at 22:35 Comment(1)
Given that the length is a defined variable, n, this would be shorter: for(var a=[];n--;a[n]=0);Omdurman
A
4

let filled = [];
filled.length = 10;
filled.fill(0);

console.log(filled);
Aspirate answered 27/7, 2019 at 21:1 Comment(0)
V
4

As of ES6 (and later versions)

You can do it like the following:

const bigNb = 1e6;
const zeros = Array(bigNb).fill(0); // array of 1M zeros
Volnay answered 11/2, 2023 at 18:12 Comment(0)
P
2

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

Pliny answered 28/7, 2015 at 20:47 Comment(1)
'0 '.repeat(200).split(' ')Sensationalism
V
2

What everyone else seems to be missing is setting the length of the array beforehand so that the interpreter isn't constantly changing the size of the array.

My simple one-liner would be Array.prototype.slice.apply(new Uint8Array(length))

But if I were to create a function to do it fast without some hacky workaround, I would probably write a function like this:

var filledArray = function(value, l) {
    var i = 0, a = []; a.length = l;
    while(i<l) a[i++] = value;
    return a;
    }
Vitalis answered 7/9, 2015 at 7:53 Comment(0)
P
2

lodash:

_.fill(array, value)

is a clean and cross-browser safe way to fill an array.

Phrygia answered 21/6, 2017 at 14:26 Comment(0)
C
2
const item = 0
const arr = Array.from({length: 10}, () => item)

const item = 0
const arr = Array.from({length: 42}, () => item)
console.log('arr', arr)
Cobaltic answered 13/3, 2021 at 11:0 Comment(0)
C
2
let arr = [...Array(100).fill(0)]
Crush answered 23/1, 2022 at 15:32 Comment(1)
Your answer could be improved with additional supporting information. Please edit your answer to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Bootless
C
2

In my testing by far this is the fastest in my pc

takes around 350ms for 100 million elements.

"0".repeat(100000000).split('');

for the same number of elements map(()=>0) takes around 7000 ms and thats a humungous difference

Cabanatuan answered 21/3, 2022 at 2:51 Comment(0)
F
1

The fastest way to do that is with forEach =)

(we keep backward compatibility for 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']
Fiske answered 11/10, 2011 at 16:20 Comment(2)
That could be faster (I haven't checked), but it only works if the array already has values in it because forEach only loops over elements that have been set. So fillArray(new Array(100), 'X') won't do anything. The fallback code for IE works in either case.Grandeur
It is not correct answer as the problem is that we DO NOT HAVE array yet. We have to make it and prepare it. Your answer uses already made array. I tested some algorithm with array of 100e6 items. Calculations was not easy but even that, preparing array from nothing takes the most time in that algorithm (80%).Pauwles
H
1

I just use :

var arr = [10];
for (var i=0; i<=arr.length;arr[i] = i, i++);
Hydroxide answered 12/8, 2013 at 8:41 Comment(1)
Code seems broken, didn't you mean something like for(var i=0, arr=[]; i<10; arr[i]=0, i++);?Hypothalamus
H
1

Another nice option found here http://www.2ality.com/2013/11/initializing-arrays.html

function fillArrayWithNumbers(n) {
  var arr = Array.apply(null, Array(n));
  return arr.map(function (x, i) { return i });
}
Hygroscopic answered 8/6, 2015 at 21:53 Comment(1)
This answer was already provided in the first answer.Fore
O
1

Recursive solutions

As noted by several others, utilizing .concat() generally provides fast solutions. Here is a simple recursive solution:

function zeroFill(len, a){
  return len <= (a || (a = [0])).length ?
    a.slice(0, len) :
    zeroFill(len, a.concat(a))
}

console.log(zeroFill(5));

And a general-purpose recursive array fill function:

function fill(len, v){
  return len <= (v = [].concat(v, v)).length ?
    v.slice(0, len) : fill(len, v)
}

console.log(fill(5, 'abc'));
Omdurman answered 23/6, 2017 at 16:20 Comment(0)
B
0

You can check if index exist or not exist, in order to append +1 to it.

this way you don't need a zeros filled array.

EXAMPLE:

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);
Benedictus answered 5/11, 2013 at 10:53 Comment(1)
Capitalization might be seen as "shouting", maybe you can edit it?Fled
S
0

The fastest here is

(arr = []).length = len; arr.fill(0);
Streamline answered 4/3, 2020 at 3:11 Comment(1)
why is this the fastest way?Peter
L
0

new Array(2).fill(0)

will create

[ 0, 0 ]

More in the docs:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill

Leventis answered 21/9, 2023 at 9:33 Comment(0)
S
-2
var str = "0000000...0000";
var arr = str.split("");

usage in expressions: arr[i]*1;

EDIT: if arr supposed to be used in integer expressions, then please don't mind the char value of '0'. You just use it as follows: a = a * arr[i] (assuming a has integer value).

Silverside answered 18/8, 2009 at 20:45 Comment(17)
My downvote sorry. This is terse but not efficient, as you will be creating a string first then performing a string operation, which tend to be slow, and you would still need to then convert the resultant strings to ints, which is also slow.Bakehouse
BTW, the question didn't state by what kind of "zeros" that array must be filled. Regarding performance - I think it should be faster than all previous solutions. Remenber .join("") for string concatenation?Silverside
Thevs - you're welcome to profile and prove me wrong. I think it's a stretch to interpret 'zero' as "the string '0'". Nobody else did. Also, just because join is fast for string concatenation does not mean split is the fastest way to create an array.Bakehouse
Ok. Let's count just statements in previous solutions. Every statement or expression (like i-- or other assignment) takes a var from internal cache, calculates an expression assigns it and so on... In split case everything works within one function and operates on one variable, Yes, I realize that '0' is not 0, but it's a little overhead to add 0 to match the integer type (if it's really needed).Silverside
@Thevs: If we can play around with the concept of "zero", I submit this is the most efficient: var a = new Array(len). undefined is falsey, and so a bit zero-like. (Whereas "0" is not falsey.) I had the impression the OP really wanted zeroes, though, not zero-like things.Ostracon
OK. How about the problem that creating a 10k element array adds 10k to your source file?Bakehouse
I just benchmarked this - it's ~33% slower in a range of crude tests and it has the more serious problem of requiring a literal string of the right length.Phoenix
@James - what exact numeric method did you benchmark? I can't find any circumstance where this is faster (IE or FF)Phoenix
@Triptych: "0" + 5 = "05" === 5. BTW, Any expression with 0, except for division is of no sense.Silverside
I was looking for numeric 0 (not the string "0") and for a parametrized length. A solution like string splitting seems more useful if you want to save some code syntax space and have varying data rather than when it's just a constant.Argenteuil
@dil: What is the practical purpose of having 0 values instead '0' values?Silverside
@Thevs: The assumption was that since the zeros will be used for numeric math that it would be more space and time efficient to just initialize them as numbers.Argenteuil
Can you give an example for using zeros in math? ;)Silverside
Sorry, for using pre-assignend zeros.Silverside
There are lots of reasons. How about counters that start at zero. Or a partially initialized matrix. Don't get caught up on the zero part of it. A generalized solution that allows arbitrary array length filled with an arbitrary value is more useful than the special case of zeros.Argenteuil
@dip: It's Ok for all these things. But then you should edit your initial question to comply to all you told here.Silverside
@dip: To be more clear: I gave an exact answer to your exact question. And in this exact case my solution is faster.Silverside
H
-2

I know this isn't the purpose of the question, but here's an out-of-the-box idea. Why? My CSci professor noted that there is nothing magical about 'cleansing' data with zero. So the most efficient way is to NOT do it at all! Only do it if the data needs to be zero as an initial condition (as for certain summations) -- which is usually NOT the case for most applications.

Humpbacked answered 26/3, 2020 at 13:38 Comment(1)
I thought of the same idea. Here's some bare-bones code that implements it using Proxy(): new Proxy(Array(length), { get(target, prop, receiver) { const value = Reflect.get(...arguments); return value !== undefined ? value : 0; } })Zepeda
L
-6

return Array( quantity ).fill(1).map( n => return n * Math.abs(~~(Math.random() * (1000 - 1 + 1)) + 1) );

One line.

Lightsome answered 24/6, 2016 at 12:8 Comment(2)
.fill() only works in newer browsers, so it creates runtime problemsMoten
SyntaxError: Unexpected token return. Other than that, the gist of your solution is Array(quantity).fill(1), which had been posted already. The rest is a distraction.Fishmonger

© 2022 - 2024 — McMap. All rights reserved.