2

I want to write a function that can deep flatten a given array. For example:

deepFlatten([]);         // []
deepFlatten([1, 2, 3]);  // [1, 2, 3] 
deepFlatten([[1, 2, 3], ["a", "b", "c"], [1, 2, 3]]); // [1, 2, 3, "a", "b", "c", 1, 2, 3]
deepFlatten([[3], [4], [5]], [9], [9], [8], [[1, 2, 3]]]);  // [3, 4, 5, 9, 9, 8, 1, 2, 3]

I try to solve this recursively and so far I've got this:

var deepFlatten = function (array){
  var result = []; 
  array.forEach(function (elem) {
    if (Array.isArray(elem)) {
        result.concat(deepFlatten(elem)); // problem probably lies here
    } else {
        result.push(elem);
    }
  });
  return result;
};

This however only pushes non-array elements to result and completely ignores the concatenating part. How can I fix this or is there a better way to write this function without the help of any external library?

Huy Tran
  • 1,770
  • 3
  • 21
  • 41

2 Answers2

7

You just need to set result to result = result.concat(deepFlatten(elem))

var deepFlatten = function (array){
  var result = []; 
  
  array.forEach(function (elem) {
    if (Array.isArray(elem)) {
        result = result.concat(deepFlatten(elem)); // Fix here
    } else {
        result.push(elem);
    }
  });
  
  return result;
};

console.log(deepFlatten([]))     
console.log(deepFlatten([1, 2, 3]))
console.log(deepFlatten([[1, 2, 3], ["a", "b", "c"], [1, 2, 3]]))
console.log(deepFlatten([[[3], [4], [5]], [9], [9], [8], [[1, 2, 3]]]))

Instead you can use reduce() and spread syntax instead of concat.

var deepFlatten = function (array){
  return array.reduce(function(r, e) {
    return Array.isArray(e) ? r.push(...deepFlatten(e)) : r.push(e), r
  }, [])
};

console.log(deepFlatten([]))     
console.log(deepFlatten([1, 2, 3]))
console.log(deepFlatten([[1, 2, 3], ["a", "b", "c"], [1, 2, 3]]))
console.log(deepFlatten([[[3], [4], [5]], [9], [9], [8], [[1, 2, 3]]]))
Nenad Vracar
  • 118,580
  • 15
  • 151
  • 176
3

Your code is mostly fine. .concat returns a new array, it doesn't modify the original. If you change

result.concat(deepFlatten(elem)); // problem probably lies here

to:

result = result.concat(deepFlatten(elem)); // problem probably lies here

i think it gives the correct results.

Halcyon
  • 57,230
  • 10
  • 89
  • 128