DEV Community

Cover image for Curious case of sparse array in JS
Vikas yadav for XenoX

Posted on

Curious case of sparse array in JS

I have never heard about sparse array before one of my colleagues shared this interesting issue.

 const range = new Array(10).map((_, i) => i);
Enter fullscreen mode Exit fullscreen mode

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]
Enter fullscreen mode Exit fullscreen mode

Let's see....

giphy

Output

image

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 use forEach.

 const range = [];
 new Array(10).forEach((_, i) => range.push[i]);
Enter fullscreen mode Exit fullscreen mode

giphy (1)

Output

image

Nooooooooooo!!

giphy (2)

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 be sparse array if one of the values at any given index is empty

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:

image

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
Enter fullscreen mode Exit fullscreen mode

Output

image

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);
Enter fullscreen mode Exit fullscreen mode

So here new Array(10) will create a sparse array of length 10.

(10) [empty × 10]
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

Output

image

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]);
Enter fullscreen mode Exit fullscreen mode

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);
Enter fullscreen mode Exit fullscreen mode

image

With new Array(length) and fill

  const a = new Array(3).fill(0).map((_, i) => i)
Enter fullscreen mode Exit fullscreen mode

Output

image

Thank you for reading.

Follow me on twitter

References

MDN Array
2ality
Freecodecamp article

Discussion (4)

Collapse
ranemihir profile image
Mihir Rane

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:

  1. Why are they called 'sparse'? What exactly is the meaning of that word?
  2. Is 'empty' a data type similar to 'undefined'? What Is the output of (empty == undefined)?

Looking forward to more such articles.

Collapse
thejsdeveloper profile image
Vikas yadav Author • Edited

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.

Collapse
ranemihir profile image
Mihir Rane

Oh I see. Thanks for your help! :)

Collapse
shadabshs profile image
Md Shadab Alam

It was a really interesting read,
Vikas explained it so well.
First time saw this use case.