DEV Community

Cover image for JavaScript Array.flat()
Nick
Nick

Posted on

JavaScript Array.flat()

Array methods in JavaScript can be super helpful. This method is no exception!

Array.flat() is a method that will in short simplify an array for you. The two big things it can do is take an array that has nested elements and return a new array with less nesting and it can remove empty array elements.

Removing nested Arrays

This is truly the biggest help of this method. The only argument that flat() takes is the depth of which you'd like to go and reduce the nesting. The default, if you provide no argument since it's optional, is flat(1) or depth 1.

Take this array for example:

const nums = [1, 2, 3, [4, 5], 6, [7, 8], 9]

We see it has two elements at indices [3] and [5] that are themselves array. What if you need the sum of these numbers? Well you could write your own function to test if the elements are arrays before adding to deal with the nesting.

Or we can use flat() and then you'd be able to use reduce() to get your sum in a much simpler way.

const nums = [1, 2, 3, [4, 5], 6, [7, 8], 9]
const flatNums = nums.flat()
console.log(flatNums) // output: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Using flat() gives a simple, one-level array. In the example above we didn't pass an argument because the default is 1 and that is as far down we needed to go.

To visualize the nesting levels check this out. Each comment will state the deepest level each array has and the number of elements. Each time we nest an array we add a level to depth. Also, just like array indices - we start at 0 and can say the first level is equivalent to depth = 0.

[1, 2, 3, 4, 5] // Depth: 0 - Elements: 5
[1, 2, 3, [4, 5]] // Depth: 1 - Elements: 4
[1, 2, [3, [4, 5]]] // Depth: 2 - Elements: 3
[1, [2, [3, [4, 5]]]] // Depth: 3 - Elements: 2

Maybe a simpler example to look at is this one:

[1, 2, 3, 4, 5] // Depth: 0 - Elements: 5
[1, 2, 3, 4, [5]] // Depth: 1 - Elements: 5
[1, 2, 3, 4, [[5]]] // Depth: 2 - Elements: 5
[1, 2, 3, 4, [[[5]]]] // Depth: 3 - Elements: 5

Now lets talk more about...

Depth

Each example above on the last line reaches a depth of 3 because that is the number of additional brackets we would need to use to reach the deepest element.

For us to reach the number 5 in this array const arr = [1, 2, 3, 4, [[[5]]]] we would need to use 4 sets of brackets in our notation.

One set to access the element where the nested arrays are stored and three sets to reach the 5. That would look like this arr[4][0][0][0]. The arr[4] grabs [[[5]]] and then the next two [0] accesses the nested arrays and finally the last [0] will grab 5.

const arr = [1, 2, 3, 4, [[[5]]]] // Depth: 3

console.log(arr[4]) // output: [[[5]]]
console.log(arr[4][0]) // output: [[5]]
console.log(arr[4][0][0]) // output: [5]
console.log(arr[4][0][0][0]) // output: 5

Looks like a headache to deal with all that bracket notation, right?

That's where flat() comes to the rescue. We can take those structures and flatten them out to be a single level array and use one set of brackets to access any element we need.

IF we know the exact depth of our deepest nested array we can simply pass in the appropriate argument.

[1, 2, 3, 4, 5] // No flat() needed
[1, 2, 3, 4, [5]] // flat(1)
[1, 2, 3, 4, [[5]]] // flat(2)
[1, 2, 3, 4, [[[5]]]] // flat(3)

Each of those will return the one-level array [1, 2, 3, 4, 5].

Now what if we're not sure of the depth needed to flatten an array? What if we're receiving this data randomly? Or if we just want a way to flatten all arrays without worrying about 'what is the deepest level'?

There is a simple way to achieve that:

const arr1 = [1, 2, 3, 4, [5]]
const arr2 = [1, 2, [3, [4, 5]]]
const arr3 = [1, 2, 3, 4, [[[[[5]]]]]]
arr1.flat(Infinity) // output: [1, 2, 3, 4, 5]
arr1.flat(Infinity) // output: [1, 2, 3, 4, 5]
arr1.flat(Infinity) // output: [1, 2, 3, 4, 5]

Passing Infinity will ensure the deepest level is always reached and return a one-level array.

Removing empty elements

One neat feature, that may not be intuitive from the name and it's other main function, of flat() is it will remove any empty elements.

const arr = [1, 2, , 3, , , 4, 5]

console.log(arr.flat()) // output: [1, 2, 3, 4, 5]

This will work also if a nested array contains or is simply empty elements.

const arr = [1, [2, ], 3, [ , ], 4, 5]

console.log(arr.flat()) // output: [1, 2, 3, 4, 5]

Why should we use flat()?

The biggest benefit of flat() is that it normalizes our array. We can use it to ensure that our array is in an easy to use format that won't give us any weird situations.

Having data in a consistent format allows us to utilize them with more consistent results and our programs to behave as we expect. At least we hope!

Discussion (4)

Collapse
codefinity profile image
Manav Misra

🆒 Hopefully, one will not need to deal with such messy 'nested' _Array_s too much! 💦

Collapse
stlnick profile image
Nick Author

Hopefully, indeed.

Collapse
mohsenalyafei profile image
Mohsen Alyafei

Thanks Nick for the post.

Collapse
stlnick profile image
Nick Author

Absolutely! Trying to hammer the info into my own head through posting and hopefully help others!