1

My goal is to write a function that will flat an array. So for example [1,[2,3]] should turn to [1,2,3]. I tried it with a recursive method as seen below, but it produces an endless loop.

function steamrollArray(arr) {

 var resultArray = [];

 function flatArray(array) {    
   for (i = 0; i < array.length; i++){
     if (Array.isArray(array[i])) {
         flatArray(array[i]);
     } else resultArray.push(array[i]);
   }
 }

 flatArray(arr);         
 return resultArray;
}

steamrollArray([1, [2,3]]);

What is my mistake?

Thanks in advance

10
  • 1
    Take a look into Array.prototype.reduce. Commented Jan 4, 2017 at 16:21
  • 2
    Also, steamrollArray([1, [2, 3]]) produces [1, 2, 3] as expected. Commented Jan 4, 2017 at 16:23
  • yes, just tested, it works on Chrome Commented Jan 4, 2017 at 16:23
  • Declare your variables, i is global, hence every call to flatArray makes it start from zero. Commented Jan 4, 2017 at 16:23
  • Additionally, if you use lodash, you can take a look at _.flattenDeep Commented Jan 4, 2017 at 16:24

2 Answers 2

5

You need to move resultArray inside of flatArray and concat the recursive call of flatArray to the result as well.

It is a good approach to see a recursion from the end, that means, you need an array as result, then you need to declare an array at start and return the array at last, or inbetween of the function.

While processing the data, you need to append the array with either a single item or with an array as result of a recursive call of a sub array. Both parts are in the if clause.

function steamrollArray(arr) {
    function flatArray(array) {
        var resultArray = [], // move inside
            i;                // declare as well
        for (i = 0; i < array.length; i++) {
            if (Array.isArray(array[i])) {
                resultArray = resultArray.concat(flatArray(array[i]));
                // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
            } else {
                resultArray.push(array[i]);
            }
        }
        return resultArray; // return result here
    }

    return flatArray(arr); // return the result of the call
}

console.log(steamrollArray([1, [2, 3]]));
console.log(steamrollArray([[1, 9, [7, 8]], [2,3]]));

Sign up to request clarification or add additional context in comments.

1 Comment

Ok, it works fine. Can you tell my why I have to make these changes?
1

You can simply do that:

var yourArray = [1, [2,3,4,5], [6,7], 8, [9]];
var result = yourArray.reduce(function(a, b) {
	if( a.constructor === Array){
		return a.concat(b);
	}
	return a;
}, []);
console.log(result);

1 Comment

this doesn't work for 'deeper' arrays e.g. [1, [[[2,3],4],5]]

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.