I recently discovered the following snippet of code on SO to aid in quickly populating an array with default values:
Array.apply(null, new Array(3)).map(function() {return 0;});
Given the behavior of the Array constructor and the apply method, the above snippet can also be rewritten as such:
Array.apply(null, [undefined, undefined, undefined]).map(function() {return 0;});
This technique is also useful when dealing with sparse arrays that you wish to populate with default values:
var sparseArr = [3,,,4,1,,],
denseArr = Array.apply(null, sparseArr).map(function(e) {
return e === undefined ? 0 : e;
});
// denseArr = [3,0,0,4,1,0]
However it is therein that two oddities arise:
sparseArr
is undefined, that term is not mapped in denseArr
sparseArr
contains only a single term (e.g. sparseArr = [1]
) or a single term followed by a single trailing undefined term (e.g. sparseArr = [1,]
), the resulting denseArr
equals [undefined x 1]
Can anyone explain this behavior?
new Array(3)
[…] can also be rewritten as[undefined, undefined, undefined]
No - as you just have seen, the array constructor creates sparse arrays so it should be rewritten as [,,,]
.
If the final term of of sparseArr is undefined
Nope. You're forgetting about trailing commata, which are optional since EcmaScript 5. Actually [1]
is just equivalent to [1,]
(both have a length of 1
).
To get sparse "slots", you will have to add additional commata:
[] // empty array
[,] // empty array
[,,] // [undefined x 1]
[,,,] // [undefined x 2]
If
sparseArr
contains only a single term, the resultingdenseArr
equals[undefined x N]
Consider what it means to call the apply
method:
Array.apply(null, [3,,4,1]) ≡ Array(3, undefined, 4, 1)
Array.apply(null, [3,4]) ≡ Array(3, 4)
Array.apply(null, [1]) ≡ Array(1)
And you know what the Array
constructor does when being called with a single numeric arguments - it creates a sparse array of that length…
You can have a trailing comma in arrays since ECMA 262. Its presence doesn't modify the content of the array in any way.
If you have two or more consecutive non trailing commas inside an array, their content is set as undefined.
Note: since undefined
in arrays has nonstandard behaviour in IE<9 I would avoid using it there. Use null
instead.
The fact that you have surprising results when sparseArr contains one item is because Array has two different constructors: if you pass it multiple arguments it creates an array with that sequence, if you pass it a single number it creates an array of length "number" filled with undefined.
new Array(1, 2, 3)
=> [1, 2, 3]
new Array(2)
=> [undefined, undefined]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With