如何解决在javascript中使用reduce和recursion来展平嵌套数组
我发现了这个有趣的代码示例,它使用 recursion
和 reduce
函数而不是 flat
来展平数组。除了以下内容,我明白了它的作用:
请说明
function flatWithRec(arr) {
const flatArray = arr.reduce((acc,item) => {
if (Array.isArray(item)) {
acc = acc.concat(flatWithRec(item));
} else {
acc.push(item);
}
return acc;
},[]);
return flatArray;
}
console.log(flatWithRec([1,[2,3,[4],[5,6,[7]]
]]))
// output: [1,2,4,5,7])
解决方法
-
累加器是一个数组。您重新分配给它一个新数组,该数组包含您在循环开始时的项目和要添加的数组项目的项目。如评论中所述,
acc.concat
返回一个新数组,其中包含传入参数的数组项。见https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat -
您需要在每次循环结束时返回累加器,以便在下一次循环中考虑新值。
-
acc = acc.concat(flatWithRec(item));
为什么要重新分配累加器?在减少功能中怎么可能?为什么在这里使用concat
?
累加器 (acc
) 是一个函数参数,可以重新分配,尽管这样做不是一个好习惯。 Concat 合并两个项(数组或其他),并返回一个新数组,因此您需要将其分配给 acc
作为当前循环的结果。
-
return acc;
为什么会返回 acc?每次调用函数时都是一个新的平面数组吗?
累加器保存减少项的当前状态,在您的情况下是每次循环后的当前平面数组。您需要返回它,以便下一个循环可以继续累积。
- 有没有办法仍然使用递归并使读者更容易理解?
我对 flatWithRec
的看法 - 总是串联,但如果它是一个数组,则在串联之前调用 flatWithRec
:
function flatWithRec(arr) {
return arr.reduce((acc,item) =>
acc.concat(
Array.isArray(item)
? flatWithRec(item)
: item
),[]);
}
const result = flatWithRec([1,[2,3,[4],[5,6,[7]]]])
console.log(result) // output: [1,2,4,5,7])
因此,reduce
方法的回调会针对数组中的每一项运行,并且从 iteration x 返回的任何内容都将作为第一个参数传递给 iteration x+1 。因此,必须确保在每次迭代期间返回正确的状态。
acc = acc.concat(flatWithRec(item))
为什么要重新分配累加器?在 reduce
函数中怎么可能?为什么在这里使用 concat
?
因此,我们将 acc
的返回值分配给 concat
,因为 concat
不会更改原始数组,而是返回一个新数组。累加器就像任何其他参数一样,因此您可以重新分配。完全没有必要使用 concat
(使用 push
和 spread
在最后查看我的解决方案)。
return acc;
为什么会返回 acc
?每次调用函数都是一个新的平面数组吗?
如前所述,您需要从回调中返回正确的状态。是的,在每次迭代期间,都会创建一个新数组(性能不佳,请参阅最后的解决方案)
有没有办法仍然使用递归并让读者更容易理解?
我不知道对读者来说更容易,但这是我使用 => functions
和 spread
的解决方案。
const flatWithRec = (arr) =>
arr.reduce((acc,item) => (
Array.isArray(item) ? acc.push(...flatWithRec(item)) : acc.push(item),acc
),[]);
console.log(flatWithRec([1,[7]]]]));
是的,有一种方法可以使用递归并使其更易于理解:
function f(A,i=0){
return i == A.length ? [] : (Array.isArray(A[i]) ? f(A[i]) : [A[i]]).concat(f(A,i+1));
}
var A = [1,[7]]]];
console.log(JSON.stringify(A));
console.log(JSON.stringify(f(A)));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。