首先,关于该Array.prototype.reduce()方法的一些注意事项。这不是该解决方案的主要功能,但对于初学者来说可能很少,所以我宁愿简单地介绍一下。
简而言之,reduce 方法将原始数组合并为一个值——它实际上可以是任何东西,从一个string或number到一个全新的数组或一个对象。为此,它遍历其子项并使用自定义函数(reducer 回调函数)处理每个子项。reducer 将始终接收有关当前迭代的数据作为参数,最重要的是:
将扩展的合并(或“累积”)值,然后传递到下一次迭代;
在此迭代中正在处理的当前子项。
因此,reduce 方法本身需要:
reducer 回调函数,如上所述;
合并值的初始状态。
有关实际操作的解释,您可以参考Mosh 的这个非常好的视频。
现在是递归的实际使用。
简单的说,递归就是一个调用自身的函数。这可以概括它,但它的适用性对于初学者来说可能有点难以捉摸。
让我们从解决问题开始:递归 !== 循环。它不是,如果您将它用于此目的,那么您只是在构建令人困惑的代码。
当我们需要迭代一个相互连接的元素(称为节点)的结构时,递归真的很闪耀,你需要处理、排序或在其中查找某些东西,而以前不知道它的大小或深度。诸如树遍历、路径查找和排序算法之类的东西是需要递归的常见场景。
那么为什么它适用于我们当前的场景呢?假设您要使用for循环展平数组:
function flatten(arr) { const newArray = []; for (const item of array) { if (Array.isArray(item)) newArray.push(...item); else newArray.push(item); } return newArray; } const array = [1, 2, [3, 4]]; // [1, 2, 3, 4]; console.log(flatten(array));
当然,这行得通,但请尝试不同的、更精细的数组结构。比方说:
const ohnoes = [1, 2, [3, [4, 5]]]; // [1, 2, 3, [4, 5]] console.log(flatten(ohnoes));
您可能意识到,n for在代码中嵌套循环以考虑n可能的层是完全不可持续的。
然而,递归思考通常是一项艰巨的任务。让我们仔细看看这个问题:
我们想要展平一个可能有子数组的数组;
但是,不能保证子数组自身会被展平。
您可能猜到我们现在也需要调用相同的函数来对数组的每个子项进行微观管理。考虑到:
该函数应该只return用扁平化的数组到达它的表达式;
递归路径最终会到达结构的底部节点——一个没有子数组的数组——然后返回它。
所有这些堆栈函数调用都被恰当地称为调用堆栈。当我们当前的堆栈最终自行解决时,我们必须期望得到的数组是——哒哒!像 1 周大的苏打水一样平淡。
现在剩下的就是将我们的递归函数放在一起:
function flattenRecursive(arr) { // loop through the children to see which requires flattening return arr.reduce( (consolidated, child) => { // check if the child is an array itself if (Array.isArray(child)) { // we need to flatten the array before including its elements in // our consolidated array, so we call flattenRecursive recursively consolidated.push(...flattenRecursive(child)); } else { // not an array, so just include it in the final array consolidated.push(child); } // return the consolidated array return consolidated; }, [], // the initial, empty array ); }
现在我们得到:
const yay = [1, 2, [3, [4, [5, [6, [[[[[7], [8, 9]]]]]]], 10]]]; // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] console.log(flattenRecursive(yay));
仅此而已!
本文地址:IT问答频道 https://www.eeeoo.cn/itwenda/903307_3.html,嗨游网一个专业手游免费下载攻略知识分享平台,本站部分内容来自网络分享,不对内容负责,如有涉及到您的权益,请联系我们删除,谢谢!