因此,我试图绕过递归,最近遇到了一个问题,无论如何,使用递归最容易解决。我试图展平各种深度数组,而我想实现的功能是:
mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];
function flattenArray(array) {
return array.map(val => {
if (typeof val !== "number") {
return flattenArray(val);
} else {
return val;
}
});
}
console.log(flattenArray(mixedArray));
现在,我希望它能输出[1,2,3,4,5,6,7,8,9],但它只是按原样返回mixedArray。我的想法是,它采用数组,并且(假设数组不仅仅是一个数字)通过条目进行映射。如果一个条目是单个数字,则它应该返回该数字,否则,它应该在该条目上调用原始函数,依此类推。希望这是一个相当基本的东西,例如语法错误(这很典型!)
请注意;我想知道为什么我的功能不能很好地解决问题。
(先感谢)
答案 0 :(得分:5)
您不能使用普通的map
方法来执行此操作,因为该方法只会返回与应用map
的数组(即顶层)中相同数量的元素。
请改为使用reduce
,然后确保使用必须添加的内容扩展已有的内容:
mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];
function flattenArray(array) {
return array.reduce( (flat, val) => {
if (typeof val !== "number") {
return [...flat, ...flattenArray(val)];
} else {
return [...flat, val];
}
}, []);
}
console.log(flattenArray(mixedArray));
您可以使用三元运算符代替if ... else
来稍微压缩代码:
mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];
const flattenArray = array =>
array.reduce( (flat, val) =>
[...flat, ...(Array.isArray(val) ? flattenArray(val) : [val])]
, []);
console.log(flattenArray(mixedArray));
...,当然,我们应该提到ESNext提案Array#flat,该提案只需一个方法调用即可完成所有工作。
mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];
console.log(mixedArray.flat(Infinity));
答案 1 :(得分:2)
问题在于将数组映射到数组不会改变它,它仍然是结果数组中的一个数组:
function flattenArray(array) {
return array.reduce((result, x) => result.concat(
Array.isArray(x) ? flattenArray(x) : x), [])
}
应该这样做,但是使用reduce而不是map。
答案 2 :(得分:1)
我将其修改为如下所示。因为您实际上是将所有元素映射到相同的元素:
mixedArray = [1, 2, [3, 4], [[5, 6], 7], 8, 9];
function flattenArray(array, out=[])
{
array.forEach(val =>
{
if (typeof val !== "number")
out = out.concat(flattenArray(val));
else
out.push(val);
});
return out;
}
console.log(flattenArray(mixedArray));