Javascript 使用rest参数将参数展平为一维数组

Javascript 使用rest参数将参数展平为一维数组,javascript,arrays,ecmascript-6,reduce,flatten,Javascript,Arrays,Ecmascript 6,Reduce,Flatten,在尝试将多维数组展平为一维数组时,我开发了以下代码() 比如说, 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 p

在尝试将多维数组展平为一维数组时,我开发了以下代码()

比如说,

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]
上面的方法似乎还可以

现在,我被要求做另一个函数,它代替了数组,对于数字和数组的混合,可以得到相同的结果

比如说,

flattenMix(1, [2, 3], 4, [5, [6]], 7);
// should return [1, 2, 3, 4, 5, 6, 7]
我通过添加rest参数稍微修改了上面的内容,这样函数就可以接受任意数量的参数。但是,我得到了一个
最大调用堆栈
错误。你知道下面的函数有什么问题吗

// 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]
更新1


下面的答案和建议表明,我应该在递归调用
flattmix(…curr)
中使用
..
扩展运算符。这样,当
curr
是一个数组(经过测试)时,
curr
的包含元素将被传递到
flattmix
函数(而不是
curr
数组)。

您的问题是在递归中发送数组作为第一个参数,而不是数组项。 您可以使用
flatten.apply(null,arr)
flatte(…arr)

//展平由数字和数组组成的参数(任意长度)
函数展平(…输入){
返回输入.reduce(函数(上、当前){
返回上一个concat(
数组.isArray(当前)?展平(…当前):当前
);
}, []);
}

log(展平(1,2,3,4,5,6,7));//应该返回[1,2,3,4,5,6,7]
很好,很简单。您的第一个方法已经可以处理数组了,因为
arguments
基本上是一个数组,所以我们可以添加一行额外的内容

//展平数组
函数数组(输入){
返回输入.reduce(函数(上、当前){
if(数组isArray(当前)){
返回上一个concat(数组(curr));
}否则{
返回上一个concat(curr);
}
}, []);
}
函数flattmix(){
返回数组([].slice.call(参数));
}

log(flattmix(1,2,3,4,5,6,7))好吧,您可以使用扩展运算符

函数展平混合(…输入){
返回输入.reduce(函数(上、当前){
if(数组isArray(当前)){
返回上一个concat(flattmix(…curr));
//                            ^^^^^^^
}否则{
返回上一个concat(curr);
}
}, []);
}

log(flattmix(1,2,3,4,5,6,7))有一个新方法Array.flat()


您的if语句必须始终解析为true。使用一个工具(比如Chrome开发工具)并逐步查看代码以找出原因。尝试
prev.concat(flattmix(…curr))-但是按照evolutionxbox的建议,它将极大地帮助您进行调试。@le\m,您的建议确实解决了这个问题。如果你把它作为一个答案,我会接受它作为一个解决方案。@PiotrBerebecki我在手机上,所以写一个答案很麻烦(没有堆栈片段等)。最好接受尼娜的回答,她的回答同样正确。相关:。@nnnnnn你这是什么意思?我不明白。我的意思是你没有解释为什么OP的代码不起作用,你给出了一个完全不同的解决方案。这比你的小技巧要好得多。请用扩展运算符替换
apply
,因为这正是
spread
@LUH3417的目的,我已经解释过这两个运算符都适用。顺便说一句,为了取笑现代JS,我也这么做了。正如你所知,
apply
最初是用来直接设置隐式
这个
参数的(当然是用来将数组的项分散到给定的函数中)。扩展运算符…只是扩展,因此更适合。@Piotr只是为了澄清它:
在函数声明中称为
rest
运算符。在函数调用中使用,它被称为
spread
运算符,并导致与
rest
完全相反的结果。rest运算符正是ES2015中
参数的替代品。
var arr1 = [1, 2, [3, 4]];
arr1.flat(); 
// [1, 2, 3, 4]

var arr2 = [1, 2, [3, 4, [5, 6]]];
arr2.flat();
// [1, 2, 3, 4, [5, 6]]

var arr3 = [1, 2, [3, 4, [5, 6]]];
arr3.flat(2);
// [1, 2, 3, 4, 5, 6]