DEV Community

loading...
Cover image for How to flatten an array using recursion in Javascript

How to flatten an array using recursion in Javascript

ip127001 profile image Rohit Kumawat Updated on ・1 min read

Problem statement: There is an array containing elements as an array and those array elements can contain other elements as an array and so on. Now we have to convert this input array to a flat array that contains elements but not an array of elements.

Example:
Input: [1,2,3,[4,5,[6,7]],8,[9,[10,11]]]
Output: [1,2,3,4,5,6,7,8,9,10,11]

Solution:

function flatten(arr) {
  let flattenArr = [];
  arr.forEach(el => {
    if(Array.isArray(el)){
      const result = flatten(el);
      result.forEach(el => flattenArr.push(el));
    } else {
      flattenArr.push(el);
    }
  });
  return flattenArr;
}

const input = [1,2,3,[4,5,[6,7]],8,[9,[10,11]]];
const output = flatten(input);

console.log(output);
Enter fullscreen mode Exit fullscreen mode

We have used recursion to solve this problem

Algorithm steps:

  • First, we iterate through the given array.
  • Then check each element:
    • if it is not an array then push the elements in an updated array.
    • if it is an array then again call the same function flatten() i.e. recursion. Then we will combine our updated array and return values of flatten() using the spread operator in ES6. This will keep flatting the updated array.

Thanks for reading. For more tech and F.R.I.E.N.D.S. discussion, let's connect on Twitter.

Discussion

pic
Editor guide
Collapse
pengeszikra profile image
Peter Vivo

Good solution, but maybe use .flat

[1,2,3,[4,5,[6,7]],8,[9,[10,11]]].flat() // [1,2,3,4,5,[6,7],8,9,[10,11]]
Enter fullscreen mode Exit fullscreen mode

flat parameter is recursion level:

[1,2,3,[4,5,[6,7]],8,[9,[10,11]]].flat(2) // [1,2,3,4,5,6,7,8,9,10,11]
Enter fullscreen mode Exit fullscreen mode
Collapse
ip127001 profile image
Rohit Kumawat Author

Thanks for reading the article and for this solution 🙌. Really appreciate it.
But yeah I covered this solution because it covers recursion as well.

Collapse
patarapolw profile image
Pacharapol Withayasakpunt
  • Why would you have unstructured data required to be flattened like that in the first place?
  • Classical solution for this would be using .reduce or an equivalent.
const flatten = (arr) => arr.reduce((prev, c) => [...prev, ...c], [])
Enter fullscreen mode Exit fullscreen mode

Then, for a more complex version.

const flatten = (arr) => arr.reduce((prev, c) => [...prev, Array.isArray(c) ? ...flatten(c) : c], [])
Enter fullscreen mode Exit fullscreen mode
Collapse
ip127001 profile image
Rohit Kumawat Author

Thanks for reading the post and for another solution. I just wanted to cover use cases of recursion.

Collapse
merri profile image
Vesa Piittinen

The good old super compatible way to do it:

function flatten(array) {
    // only mutate what you own, thus create a new copy
    array = array.slice(0);
    for (i = 0; i < array.length; i++) {
        // Array.isArray(array[i])
        if (Object.prototype.toString.call(array[i]) === '[object Array]') {
            // replaces single item with all items from the array
            Array.prototype.splice.apply(array, [i, 1].concat(array[i--]));
        }
    }
    return array;
}
Enter fullscreen mode Exit fullscreen mode

This should work with pretty much any JavaScript engine released within last 20 years, and does it without recursion.

But as others are saying you should just use .flat() these days instead of reinventing the wheel.

Collapse
ip127001 profile image
Rohit Kumawat Author

Thanks for reading the article and for this solution 🙌. Really appreciate it.
But yeah I covered this solution because it covers recursion as well.

Collapse
edouardsouan profile image
RWRFyZA

Hello ^^. Nice use of recursion !

For the sake of discussion, here is another solution using built-in methods of Array :

const input = [1,2,3,[4,5,[6,7]],8,[9,[10,11]]]

let output = input.reduce((flattenArr, el)=>{
  if(Array.isArray(el)){
    flattenArr = flattenArr.concat(el.flat(2))
  }else{
    flattenArr.push(el)
  }
  return flattenArr
}, [])

console.log(output)
Enter fullscreen mode Exit fullscreen mode

One could argue that if your input's data are nested to a higher level, you will have to adapt the flat() method accordingly, which is not an issue in your code.
But won't you be suppose to know the shape of the data you're working with ^^ ?

Thank you for your time and showing us that recursion is not terrifying !

Collapse
ip127001 profile image
Rohit Kumawat Author

Thanks for reading the article and for this solution 🙌. Really appreciate it. But yeah I covered this solution because it covers recursion as well.