展平数组:0来自哪里?

时间:2017-02-24 19:10:13

标签: javascript arrays function function.prototype

这个挑战是在没有定义任何新功能的情况下展平数组:

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

我的解决方案不起作用,但真正让我感到困惑的是,我不知道0来自哪里:

// 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]]

我希望代码的行为类似于follow,它按预期工作:

// 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]

我在Node,Chrome和Firefox中测试过并获得了相同的结果。

那么0来自何处以及为什么解决方案1和解决方案2为flattened生成不同的值?

3 个答案:

答案 0 :(得分:6)

reduce的回调并不只有两个参数。实际上它有四个:累加器,当前值,索引和原始数组。

您的解决方案#1相当于

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

或等效

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

这是错误的。

另请注意,您的两个解决方案实际上并未压缩超过两个维度的数组。

答案 1 :(得分:2)

.concat()正在联接.reduce(function(a,b,index,array) {})

的所有参数

答案 2 :(得分:0)

在这种情况下无需简化将const连接到新的const或var。

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

虽然想要理解这个问题的学术部分是勇敢的,但是你可以更好地理解基类方法本身的基本用法,因为它们的构建是为了帮助冗余的用例而不需要用于耦合/嵌套/链接大部分。