8

I'm trying to flatten nested arrays while preserving the order, e.g. [[1, 2], 3, [4, [[5]]]] should be converted to [1, 2, 3, 4, 5].

I'm trying to use recursion in order to do so, but the code below does not work and I don't understand why. I know there are other methods to do it, but I'd like to know what's wrong with this.

function flatten (arr) {
  var newArr = [];
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      flatten(arr);
    } else {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

flatten([[1, 2], 3, [4, [[5]]]]);

Thanks

3
  • 5
    What is the steamroller function? Commented Jun 1, 2015 at 20:11
  • Sorry, it's one of the freecodecamp challenges and I changed the name for something more descriptive, but I forgot that one. That's not the issue though. Commented Jun 1, 2015 at 20:18
  • See my recursive version of array flattening in this stackoverflow page Commented Apr 18, 2021 at 8:20

7 Answers 7

14

When calling flatten recursively, you need to pass arr[i] to it and then concat the result with newArr. So replace this line:

flatten(arr);

with:

newArr = newArr.concat(flatten(arr[i]));
Sign up to request clarification or add additional context in comments.

Comments

5

Here's a common pattern that I regularly use for flattening nested arrays, and which I find a bit more clean due to its functional programming nature:

var flatten = (arrayOfArrays) =>
    arrayOfArrays.reduce((flattened, item) =>
        flattened.concat(Array.isArray(item) ? flatten(item) : [item]), []);

Or for those who like a shorter, less readable version for code golf or so:

var flatten=a=>a.reduce((f,i)=>f.concat(Array.isArray(i)?flatten(i):[i]),[]);

1 Comment

Line Array.isArray(item) ? flatten(item) : [item]: [item] should be item => Array.isArray(item) ? flatten(item) : item
1

Here is some working code

function flatten (arr) {
  var newArr = [];
  for (var i = 0; i < arr.length; i++) {
    if (Array.isArray(arr[i])) {
      var temp = flatten(arr[i]);
      temp.forEach(function(value){ newArr.push(value); })
    } else {
      newArr.push(arr[i]);
    }
  }
  return newArr;
}

Comments

1

Havent tested it, bit this part

if (Array.isArray(arr[i])) {
      flatten(arr);
    } else {

Seems to be intended as

if (Array.isArray(arr[i])) {
  flatten(arr[i]);
} else {

3 Comments

Where's the difference?
@Bergi difference is in passing a [i] instead of a. But one thing missing here -as OrenD mentioned is concatenation of results
Ah, you should've stated that explicitly in your answer. I only spotted the changed indentation.
0

This solution is without using any Array methods

//1 >> loop inside parent
//2 >> if the element is not an array then push it in array that has to be returned or else loop inside it

const arr = [[0, 1], [2, 3], [4, 5, [6, 7, [8, [9, 10]]]]]

function toFlatArray(arr) {
  let flatArray = [];
  function rec(a) {
    if (!Array.isArray(a)) {
      flatArray.push(a);
    } else {
      for (let i = 0; i < a.length; i++) {
        rec(a[i]);
      }
    }
  }
  rec(arr);
  return flatArray;
}



const flatArray = toFlatArray(arr);

console.log("flatArray", flatArray);

1 Comment

..This solution is without using any Array methods... Please explain what is the benefit of your answer compared to others
0

Easy to understand solution:

var flatten = function(array) {
    let flatArray = [];
  
  array.forEach(element => {
    if (Array.isArray(element)) {
      let inner = flatten(element);
      flatArray.push(...inner)
    } else {
        flatArray.push(element);
    }
  })
  
  return flatArray;
};

Comments

0

Recursive Solution!


let newArray = [];
function arrayFlat(array){
    for(let i = 0; i< array.length; i++){
        if(!array[i].length) { newArray.push(array[i])};
        arrayFlat(array[i]);
    }
    console.log(newArray);
}

arrayFlat(arrayData);

// Array to be flattened.
arrayData = [1,2,[3,4],[[5,6],7]];

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.