Flat Earth Society
An excerpt from JavaScript Brain Teasers by Faraz K. Kelhini
Guess the output of the following program:
const nestedArray = ["apple", ["blueberry", "blackberry"],
["tangerine", "orange"], "grape"];
const newArr = [].concat.apply([], nestedArray);
console.log(newArr);
Try to guess what the output is before moving to the next section.
This code will output:
[‘apple’, ‘blueberry’, ‘blackberry’, ‘tangerine’, ‘orange’, ‘grape’]
Discussion
This JavaScript code is all about flattening an array of arrays. First, we have an array called nestedArray
. It contains four elements: two strings and two sub-arrays. The second line of code does the magic of flattening the array. Here’s how it works:
[]
creates an empty array. This will be the initial value for theconcat()
method.concat()
is a built-in JavaScript array method that is used to merge two or more arrays together. It takes one or more arrays as arguments and returns a new array containing the elements of all the input arrays combined.apply()
is a method that allows you to call a function with a given this value and an array (or an array-like object) as arguments. In this case, we are using it to apply the concat method to the empty array[]
while passing the elements ofnestedArray
as arguments.
So, when you run [].concat.apply([], nestedArray)
, it essentially takes all the elements from nestedArray
and concatenates them into a single, flat array. This is a common technique for flattening nested arrays in JavaScript.
But, this doesn’t seem like the most elegant solution, does it?
Fortunately, since ES2019, there’s a handy method called flat()
that allows you to quickly flatten a nested array by collapsing all sub-arrays into a single-dimensional array.
Here’s how you can use the flat()
method:
const nestedArray = ["apple", ["blueberry", "blackberry"],
["tangerine", "orange"], "grape"];
const flattenedArray = nestedArray.flat();
console.log(flattenedArray);
// → ["apple", "blueberry", "blackberry", "tangerine", "orange", "grape"]
flat()
magically goes through all the levels of nesting and creates a single-dimensional array. But wait, there’s more! You can also provide an optional parameter called depth
to control how many levels of nesting it will flatten.
By default, depth is set to 1
, meaning it flattens just one level, but you can specify a different depth if you want to go deeper. If you set the depth to Infinity
, it will flatten all levels, no matter how deep they go:
const deeplyNestedArray = ["a", ["b", ["c", ["d", ["e"]]]]];
const flattenedArray = deeplyNestedArray.flat(Infinity);
console.log(flattenedArray);
// → ["a", "b", "c", "d", "e"]
Just remember that when you use flat()
, it creates a brand new array and leaves the original array untouched. If you don’t need the original array anymore, you can directly assign the flattened array to the same variable.
We hope you enjoyed this excerpt from JavaScript Brain Teasers by Faraz K. Kelhini. You can purchase the ebook, now in beta, directly from The Pragmatic Bookshelf:
Share your questions, comments, and errata on the book’s forum page: