DEV Community

Dhilip kumar
Dhilip kumar

Posted on

Array Flattening in 5 lines

Hello there ๐Ÿ‘‹,

Array flattening is a process of reducing a Multi Dimensional Array into a single dimensional Array or with the dimensions specified.

Example:

Input: [1, 2, 3, 4, [5, 6]]

Output: [1, 2, 3, 4, 5, 6]

Thought Process:

Step 1: We should iterate over the given array.
Step 2: For Each element if it is not an array push it into the new array.
Step 3: If it is an array repeat Steps 1 to 3.

Observations:

  • We use the output of one iteration in the next, so the idea here is to use Array.reduce().
  • Since there is a repetition of steps 1 to 3 on getting an Array as input, we will have to do a recursion.

Lets get into coding:

function flattenArr(arrToFlatten) {
    return arrToFlatten.reduce((acc, value) => {
      if (value instanceof Array) {
        return acc.concat(flattenArr(value));
      }
      return acc.concat(value);
    }, []);
}
Enter fullscreen mode Exit fullscreen mode

Call it as:


const arr = [1, 2, 3, 4, [5, 6]];
flattenArr(arr) // [1, 2, 3, 4, 5, 6]

Enter fullscreen mode Exit fullscreen mode
  • flattenArr is a function that accepts arrToFlatten of type Array as Argument.
  • We return the output of arrToFlatten.reduce.
  • Let the initial value of the result be empty array []
  • If the current input value is not an Array's instance add it to the acc using concat utility function.
  • If that turns out to be an instanceof an Array then call flattenArr again with the Array(value) as a parameter, then concat that with acc.

So now, with this approach we can reduce any Multi Dimensional Array into a Single Dimensional Array.

How about the case where we need it to flatten only upto specified levels deep and anything nested inside that should remain as it is?

Its simple we get another value from the user in the argument(depth).

function flattenArr(arrToFlatten, depth) {
    return arrToFlatten.reduce((acc, value) => {
      if (value instanceof Array && depth > 0) {
        return acc.concat(flattenArr(value, depth - 1));
      }
      return acc.concat(value);
    }, []);
}
Enter fullscreen mode Exit fullscreen mode

Call it as:


const arr = [1, 2, 3, 4, [5, 6, [7, 8]]];
flattenArr(arr, 1) // [1, 2, 3, 4, 5, 6, [7, 8]]

Enter fullscreen mode Exit fullscreen mode
  • Add an additional parameter depth and check if its value is greater than 0 before processing an array inside the Reduce function.

  • If the depth value is greater than 0 it means the Array has to be flattened. So recursively call flattenArr with the array and depth - 1 as we have gone in one level.

  • Each recursive call means we are going 1 level deep so we reduce the value of depth by 1

Oh yeah, I was saying 5 lines. Here you go!!!

const flattenArr = (arrToFlatten, depth) => (
    arrToFlatten.reduce((acc, value) => (
      ((value instanceof Array && depth) ? [...acc, ...flattenArr(value, depth - 1)] : [...acc, value])
    ), [])
);
Enter fullscreen mode Exit fullscreen mode

Handling edge cases:

  • What if the first parameter is not an array?
  • What if depth is not a number?

Lets add a check:

 const typeOfDepth = typeof(depth);
 if (!(arrToFlatten instanceof Array) || !(typeOfDepth === 'number')) {
    throw new Error('Invalid Argument Supplied');
 }

Enter fullscreen mode Exit fullscreen mode

As George suggested in the comment below, we do have default Array.flat() method however to attain browser support you will have to get help from your js transpilers like babel.

My Website, blogs and Twitter

Thats all Folks!!!

Discussion (7)

Collapse
georgecoldham profile image
George

You may also like Array.flat()

Supported on all browsers except edge and ie. if you are already using Babel then you can use without issue.

Collapse
kaos profile image
Kai Oswald

HOW TO FLATTEN AN ARRAY WITH JUST 1 LINE OF CODE! DEVS HATE HIM

Collapse
dhilipkmr profile image
Dhilip kumar Author

Post here is to understand how we could write utility functions ourselves. Getting to know what's happening under the Hood.๐Ÿ˜…

Collapse
georgecoldham profile image
George

Oh absolutely! Itโ€™s a valuable thing being able to understand whatโ€™s going on behind the scenes.

I only suggested .flat() incase you or others werenโ€™t aware of it. As Its a relatively new addition.

Thread Thread
dhilipkmr profile image
Dhilip kumar Author

Sure thing Agreed. I'll add about Array.flat too in the above Post . ๐Ÿ˜„

Collapse
pclement_ profile image
Peter Clement

Nice post! Thanks!

I've found this is a super common interview question, not so much in person / white boarding, but definitely online screens.

Collapse
dheerajmalik1 profile image
Dheeraj Malik

That gif :D