flattening an array: where does the 0 come from?

104 views Asked by At

This challenge is to flatten an array without defining any new functions:

// challenge
const arr = [1, [2]]
const flattened = arr.reduce(/*your code here, no function expressions or declarations allowed*/, [])
console.log(flattened) // expected: [1, 2]

My solution doesn't work, but what really bugs me is that I have no idea where the 0 is coming from:

// Solution 1
const arr = [1, [2]]
const flattened = arr.reduce(Function.prototype.call.bind(Array.prototype.concat), [])
console.log(flattened) // unexpected result: [1, 0, 1, [1], 2, 1, 1, [1]]

I'd expected the code to behave like the follow, which works as expected:

// Solution 2
const arr = [1, [2]]
const flattenReducer = (x, y) => Function.prototype.call.bind(Array.prototype.concat)(x, y)
const flattened = arr.reduce(flattenReducer, [])
console.log(flattened) // logs the expected result: [1, 2]

I tested in Node, Chrome, and Firefox and got the same results.

So where is the 0 coming from and why do Solution 1 and Solution 2 produce different values for flattened?

3

There are 3 answers

1
Derek 朕會功夫 On BEST ANSWER

reduce's callback doesn't only have two arguments. In fact it has four: accumulator, current value, index, and the original array.

Your solution #1 is equivalent to

arr.reduce(function (x, y, z, a) {
    return Function.prototype.call.bind(Array.prototype.concat)(x, y, z, a);
}, []);

or equivalently

arr.reduce(function (x, y, z, a) {
    return x.concat(y, z, a);
}, []);

which is wrong.

Also note that both of your solutions doesn't actually flatten arrays with more than two dimensions.

9
Brian Ellis On

There's no need for reduce in this situation simply concat the const to new const or var.

const arr = [1, [2]];
var arrFlat = [].concat.apply([], arr);
console.log(arrFlat);

While wanting to understand the academic portions of this issue are valiant you'd be much better served understanding the basic usage of the base class method itself as they've been built to aid redundant use cases without the need for coupling/nesting/chaining for the most part.

0
guest271314 On

.concat() is concatenating all of the parameters at .reduce(function(a,b,index,array) {})