4

I'm trying to flatten an array with randomly nested arrays inside. I'm not sure why the function I wrote ends up in an infinite loop:

let array = [1, 2, [3]]
var final_array = [] 

function flattener(array){
  for(i = 0; i < array.length; i++){
    if(array[i] instanceof Array){
      flattener(array[i])
    }else{
      final_array.push(array[i])
    }
  }
}

flattener(array)

What I think SHOULD happen is:

When I'm in the for loop checking for [3], it goes into the if statement, flattener gets called again, it resolves, and then I exit the if statement.

Instead, the if statement keeps calling to check [3] infinitely, and I'm not sure why this happens.

1
  • Setting a breakpoint and running through line by line would've probably shown you what is going wrong. Commented Mar 12, 2017 at 4:30

4 Answers 4

8

The problem is you didn't declare the i variable, so it's leaking into the global space and being reset when it recurses.

Change:

for(i = 0; i < array.length; i++){

To:

for(var i = 0; i < array.length; i++){
Sign up to request clarification or add additional context in comments.

1 Comment

oh my god. THANK YOU SO MUCH I LOVE YOU.
2

This is another approach using Array.reduce and Array.concat.

/**
 * Flattens an array of arrays into one-dimensional array
 * @param  {Array} arr: the array to be flattened
 * @return {Array}
 */
function flatten(arr) {
  return arr.reduce(function (flattened, cvalue) {
    return flattened.concat(Array.isArray(cvalue) ? flatten(cvalue) : cvalue);
  }, []); // initial value of flattened array []
}

Testing it...

let array = [1, 2, [3]]
var falttened = flatten(array)

Take a look at his gist: Array flatten

Comments

2

Array#concat plus Array#map is yet another way you can achieve this

var flattener = arr => [].concat.apply([], arr.map(item=>Array.isArray(item) ? flattener(item) : item));

or the ES5 version

var flattener = function flattener(arr) {
  return [].concat.apply([], arr.map(function (item) {
    return Array.isArray(item) ? flattener(item) : item;
  }));
};

Comments

1

Change

 for(i = 0; i < array.length; i++)

to

 for(var i = 0; i < array.length; i++)

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.