Piotr Berebecki Piotr Berebecki - 4 months ago 10
Javascript Question

Flatten arguments into one dimensional array using the rest parameter

I've developed the following code (http://codepen.io/PiotrBerebecki/pen/KrkdPj) when trying to flatten a multidimensional array into a one-dimensional array.

For example,

flattenArray([1, [2, 3], 4, [5, [6]], 7])
// should return [1, 2, 3, 4, 5, 6, 7]


// Flatten an array
function flattenArray(input) {
return input.reduce(function(prev, curr) {
if (Array.isArray(curr)) {return prev.concat(flattenArray(curr));}
else {return prev.concat(curr);}
}, []);
}

console.log( flattenArray([1, [2, 3], 4, [5, [6]], 7]) );
// [1, 2, 3, 4, 5, 6, 7]


The above seems to work OK.

Now, I've been asked to make another function that instead of an array will achieve the same result for a mix of numbers and arrays.

For example,

flattenMix(1, [2, 3], 4, [5, [6]], 7);
// should return [1, 2, 3, 4, 5, 6, 7]


I've slightly modified the above by adding the rest parameter so that the function can accept an arbitrary number of arguments. However I'm getting a
maximum call stack
error. Would you know what the problem is with the function below?

// Flatten arguments (arbitrary length) consisting of a mix of numbers and arrays
function flattenMix(...input) {
return input.reduce(function(prev, curr) {
if (Array.isArray(curr)) {return prev.concat(flattenMix(curr));}
else {return prev.concat(curr);}
}, []);
}

console.log( flattenMix(1, [2, 3], 4, [5, [6]], 7) ); // should return [1, 2, 3, 4, 5, 6, 7]


UPDATE 1

The answer and suggestions below have indicated that I should be using the
...
spread operator in the recursive call
flattenMix(...curr)
. In this way when the
curr
is an array (as tested) then the containing elements of the
curr
would be passed in to the
flattenMix
function (instead of the
curr
array).

Answer

Well, you could just use the spread operator.

function flattenMix(...input) {
    return input.reduce(function (prev, curr) {
        if (Array.isArray(curr)) {
            return prev.concat(flattenMix(...curr));
            //                            ^^^^^^^
        } else {
            return prev.concat(curr);
        }
    }, []);
}

console.log(flattenMix(1, [2, 3], 4, [5, [6]], 7));