![](/img/trans.png)
[英]Flatten array of multiple nested arrays without recursion - javascript
[英]Use reduce and recursion in javascript to flatten nested array
我发现了这个有趣的代码示例,它使用recursion
来展平数组并reduce
function 而不是flat
。 我得到了它的作用,除了以下内容:
acc = acc.concat(flatWithRec(item));
为什么累加器被重新分配? 如何减少 function? 为什么在这里使用concat
?
return acc;
为什么 acc 被退回? 每次调用 function 时,它是一个新的平面阵列吗?
有没有办法仍然使用递归并使读者更容易理解?
请说清楚
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, 3, 4, 5, 6, 7])
累加器是一个数组。 你重新分配它,给它一个新数组,其中包含你在循环开始时拥有的项和要添加的数组项的项。 正如评论中所说, acc.concat
返回一个新数组,其中包含传入参数的 arrays 的项目。 请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat
您需要在每个循环结束时返回累加器,以便在下一个循环中考虑新值。
acc = acc.concat(flatWithRec(item));
为什么累加器被重新分配? 如何减少 function? 为什么在这里使用concat
? 累加器 ( acc
) 是一个 function 参数,可以重新分配,尽管这样做不是一个好习惯。 Concat 结合两个项目(数组或其他),并返回一个新数组,因此您需要将其分配给acc
作为当前循环的结果。
return acc;
为什么 acc 被退回? 每次调用 function 时,它是一个新的平面阵列吗?累加器保存减少项目的当前 state,在您的情况下,每个循环后的当前平面数组。 您需要将其返回,以便下一个循环可以继续累积。
我对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, 3, 4, 5, 6, 7])
因此, reduce
方法的回调针对数组中的每个项目运行,并且从迭代 x返回的任何内容都作为第一个参数传递给迭代 x+1 。 因此,必须确保在每次迭代期间返回正确的 state。
acc = acc.concat(flatWithRec(item))
为什么要重新分配累加器? 如何reduce
function? 为什么在这里使用concat
?
因此,我们将concat
的返回值分配给acc
,因为concat
不会更改原始数组,它会返回一个新数组。 累加器就像任何其他参数一样,因此您可以重新分配。 完全不需要使用concat
(请参阅最后使用push
和spread
的解决方案) 。
return acc;
为什么acc
被退回? 每次调用 function 时,它是一个新的平面阵列吗?
如前所述,您需要从回调中返回正确的 state。 是的,在每次迭代期间,都会创建一个新数组(这不是那么高效,请参阅最后的解决方案)
有没有办法仍然使用递归并让读者更容易理解?
我不知道对读者来说更容易,但这是我使用=> functions
和spread
的解决方案。
const flatWithRec = (arr) => arr.reduce((acc, item) => ( Array.isArray(item)? acc.push(...flatWithRec(item)): acc.push(item), acc ), []); console.log(flatWithRec([1, [2, 3, [4], [5, 6, [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, [2, 3, [4], [5, 6, [7]]]]; console.log(JSON.stringify(A)); console.log(JSON.stringify(f(A)));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.