Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?

The World of Sparse Arrays in JavaScript

Me: The size of an array is set by the variety of its components, proper?

JavaScript: Hmm, probably not . . .

Ah, JavaScript arrays! 😊

At first look, they appear so easy, only a linear assortment of things, proper? However dig a little bit deeper, and you will find some surprises. Name them simply one other nod to the typically perplexing nature of JavaScript.

On this put up I’ll speak about:
βœ… what determines the size of an array
βœ… the distinction between sparse and dense arrays
βœ… work with sparse arrays

The Case of the Mysterious Array Size

Bear in mind the primary time you thought you’d mastered arrays? Similar. I believed the array size was decided by the variety of outlined components. However alas, JavaScript had different plans.

Sparse Arrays

Let’s create an empty array:

let arr = []  βœ…
Enter fullscreen mode

Exit fullscreen mode

Seems to be innocent, proper? Now let’s put a component at index 2:

arr[2] = 5  βœ…
Enter fullscreen mode

Exit fullscreen mode

What do you assume arr.size could be? In case you stated 1, be part of the membership of the fooled!

console.log(arr.size) -> 3  😱
Enter fullscreen mode

Exit fullscreen mode

Sure, arr.size is 3, not 1!

In JavaScript, arr.size = highest index + 1 (plus 1 as a result of we begin indexing at 0).

It is true, this isn’t your on a regular basis array. It is what we name a sparse array. And in the event you’re questioning what a sparse array is, attempt logging the array to the console:

console.log(arr) -> [ <2 empty items>, 5 ]  πŸ€”
Enter fullscreen mode

Exit fullscreen mode

You will discover that there are two empty spots previous the worth 5. These empty spots, referred to as additionally holes, make the array sparse, because it accommodates gaps the place no specific values have been set.

Consider it like a car parking zone the place you resolve to park your automotive in a spot marked #10. This suggests that there are 9 different spots earlier than it. Even when these previous spots are empty, the car parking zone continues to be thought-about to have a capability of 10 spots.

JavaScript arrays function on the identical precept: marking a spot at index 2 means there are two different spots earlier than it (at indices 0 and 1), making the array’s size 3.

Dense Arrays

In distinction, chances are you’ll be extra accustomed to dense arrays, the place each index corresponds to a price, even when it is set to undefined.

let dense = [ "dense", "arrays", "are", "boring"]  πŸ˜‰
Enter fullscreen mode

Exit fullscreen mode

In dense arrays, there are not any gaps; every slot within the array is accounted for, whether or not it is holding a price or is explicitly undefined.

Sparse Array Meets map( )

A Shock

So, you may marvel, what occurs once you run the map() operate on our sparse array?

const newArr = arr.map(x => x + 3)

console.log(newArr) -> [ <2 empty items>, 8 ]  😲
Enter fullscreen mode

Exit fullscreen mode

Anticipated to see NaN (ie “Not-a-Quantity”)? So did I. However it seems that map() simply ignores the empty spots!

Consider a sparse array as a car parking zone divided into two sections: free parking and paid parking. Free parking areas are just like the empty slots in our array. Our parking officer – the map() operate – ignores them and walks proper previous them.

A Query

A good query to ask: if the empty spots are ignored, why aren’t they simply eradicated from the brand new array? As a result of after our parking officer finishes their rounds, the car parking zone (our array) should stay the identical dimension!

Equally, JavaScript’s map() methodology will all the time return a brand new array of the identical size as the unique. It does not get rid of empty spots; it retains them as they’re, making certain that the size of the array stays constant.

An Experiment

Now let’s explicitly set the primary factor as undefined:

arr[0] = undefined
console.log(arr) -> [ undefined, <1 empty item>, 5 ]  βœ…

const newArr = arr.map(x => x + 3)

console.log(newArr) -> [ NaN, <1 empty item>, 8 ]  😲
Enter fullscreen mode

Exit fullscreen mode

Discover how the primary factor of the brand new array is now NaN. Why?

Once we use map() on an array in JavaScript, the operate we offer as an argument is known as on every index that has been assigned a price. We all know it ignores the empty spots, nevertheless it does take note of each factor with an assigned worth. Even when that worth is undefined!

So if we explicitly set a component to undefined, map() will certainly invoke the operate on that factor. In our particular instance of arr.map(x => x + 3), the operate is making an attempt so as to add 3 to undefined. In JavaScript, any arithmetic operation involving undefined will output NaN.

To exhaust our car parking zone analogy: when an array factor is explicitly set to undefined, it is like a metered however unoccupied spot within the paid parking part. Our parking officer (once more, the map() operate) walks by and makes word of it. In JavaScript phrases, which means listening to that worth and attempting to work with it.

A Observe

Within the above instance, we acquired fortunate. JavaScript will mechanically convert undefined to NaN when it tries to carry out an arithmetic operation. The map() operate will then proceed to function on the remainder of the weather within the array.

It’s completely different with strings. When map() encounters undefined and the operate is attempting to, let’s say, convert it to lowercase, you may run right into a TypeError as a result of undefined shouldn’t be a string and doesn’t have a toLowerCase() methodology. The execution stops at that time.

const array = ['HELLO', 'WORLD', undefined]

const newArray = array.map(factor => factor.toLowerCase())  🚫
//TypeError: Can not learn properties of undefined 
Enter fullscreen mode

Exit fullscreen mode

To make sure your code runs easily, it is important to deal with undefined values earlier than calling any strategies on them: filter them out earlier than making use of map() or use a try-catch block. And naturally, don’t purposefully declare your components as undefined! We did it right here within the title of studying. 😊

Sparse Array Meets filter()

Should not we simply filter out the empty spots as nicely? In fact! You possibly can filter out empty spots by utilizing the filter() methodology. Bear in mind how map() ignores them? Nicely, the empty slots are being handled as undefined for the aim of filtering!

Let’s take our up to date array and apply filter() to it. The array has undefined at first index, adopted by an empty spot, and worth 5 at index 2.

console.log(newArr) -> [ undefined, <1 empty item>, 5 ]

const filteredNewArr = newArr.filter(x => x !== undefined);

console.log(filteredNewArr) -> [5]  βœ…

Enter fullscreen mode

Exit fullscreen mode

Okay, however what if, theoretically, you solely wish to take away the holes however hold the undefined? You are able to do one thing like:

const filteredNewArr = newArr.filter((merchandise, index) =>         

console.log(filteredNewArr) -> [ undefined, 5 ]  βœ…
Enter fullscreen mode

Exit fullscreen mode

On this instance, hasOwnProperty() checks if the array has an precise worth, together with undefined, at every index. Due to this fact, it should return true for all indices the place a price exists and false for holes.

To Recap

βœ”οΈ Not all array are dense. Some have holes and we name them sparse.

βœ”οΈ For the aim of discovering the size, we should rely the holes as nicely.

βœ”οΈ The map() methodology ignores the holes, nevertheless it doesn’t take away them.

βœ”οΈ We are able to take away the holes with the filter() methodology.

Are We Able to Conclude?

Is a sparse array a factor in real-world purposes? I don’t have a solution but, and promise to replace the put up if and once I do. However then, even when the reply is a powerful no, it doesn’t matter. It will not make these quirky sides of JavaScript arrays any much less fascinating to discover. Lengthy reside quirkiness!

Hold exploring! β›΅


JavaScript: The Definitive Information
seventh Version, by David Flanagan
O’Reilly Media, 2020

Weblog put up initially revealed on August 1, 2023 on corinamurg.dev.

Credit score: Picture by Krzysztof Kotkowicz on Unsplash

Add a Comment

Your email address will not be published. Required fields are marked *

Want to Contribute to us or want to have 15k+ Audience read your Article ? Or Just want to make a strong Backlink?