I have never heard about sparse
array before one of my colleagues shared this interesting issue.
const range = new Array(10).map((_, i) => i);
This code looks good to me. What can go wrong!! It should create the array of length
10
which will have values ranging from 0 - 10
.
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Let's see....
Output
Whhaaaatttt on the earth is that output.....!!!!
The length of the array is 10
but when we try to access the value at index 0
the output is undefined
. Same for other indices.
Ok. That is super weird. Next thing that usually comes to mind is this:
map
isn't working. Let's useforEach
.
const range = [];
new Array(10).forEach((_, i) => range.push[i]);
Output
Nooooooooooo!!
Earlier, at-least we had length 10
which was what we expected. But now we lost that too. As you can see above in the output that length
of range
is 0
and since length
is 0
that's why no element at any indices, that's why we get undefined
at range[0]
Code looks correct, then why is it that output is unexpected.
Actually all these unexpected behaviour is caused by sparse
array.
OK. So what on earth is sparse array ?
Enter the maze
Sparse Array
Any
array
will besparse
array if one of thevalue
s at any givenindex
isempty
Empty value does not mean undefined
or null
. Empty mean that there is no value at all.
So in above example if I print range
in chrome
browser console. This will be the output:
Basically new Array(length)
will create an array of specified length but all the values will be empty
. It's like array has holes
in it.
You can create the sparse
array by following:
const range = [,,,];
const numbers = [1,2,,4];
const planets = ['earth', 'venus', 'mars'];
delete planets[1];
// when we delete element at certain index it creates a hole
Output
Explanation of the real issue
Now we know about sparse
array. So let's begin with our initial problem.
Scenario 1 : map
const range = new Array(10).map((_, i) => i);
So here new Array(10)
will create a sparse
array of length
10
.
(10)ย [empty ร 10]
Now what will happen when we call map
on sparse
array ?
As per MDN Docs
Due to the algorithm defined in the specification, if the array which map was called upon is sparse, resulting array will also be sparse keeping same indices blank.
As our whole array is sparse
that is why resulting array is also sparse
and all the values are blank
or empty
.
If we have following code, result will be different
[1,2,,4].map((num, i) => i * num)
Output
As you can see that callback
of map
does not do anything on the index
which is empty
.
Scenario 2: forEach
const range = [];
new Array(10).forEach((_, i) => range.push[i]);
As per MDN Example
No operation for uninitialised values (sparse arrays)
Which simply means that the callback
will not be invoked for empty
values.
As our whole new array is sparse
, callback will be skipped for all the elements and no value is pushed to range
array.
Other ways to create range
With Array.from
Array.from({length: 5}, (_, i) => i);
With new Array(length) and fill
const a = new Array(3).fill(0).map((_, i) => i)
Output
Thank you for reading.
Follow me on twitter
Top comments (4)
I've been coding with javascript for a long time but didn't know about this at all. Thanks for broadening my knowledge!
More questions:
Looking forward to more such articles.
Thank you for reading. ๐ I am not sure about exact reason to name it like this. I guess because arrays are supposed to be contiguous and sparse means scattered that's why they are called sparse.
To answer your second question. Empty is not a data type. And this hole is represented as
empty
in chrome browser. I think safari has different way to show this.Oh I see. Thanks for your help! :)
It was a really interesting read,
Vikas explained it so well.
First time saw this use case.