繁体   English   中英

在 javascript 中使用 reduce 和 recursion 来展平嵌套数组

[英]Use reduce and recursion in javascript to flatten nested array

我发现了这个有趣的代码示例,它使用recursion来展平数组并reduce function 而不是flat 我得到了它的作用,除了以下内容:

  1. acc = acc.concat(flatWithRec(item)); 为什么累加器被重新分配? 如何减少 function? 为什么在这里使用concat

  2. return acc; 为什么 acc 被退回? 每次调用 function 时,它是一个新的平面阵列吗?

  3. 有没有办法仍然使用递归并使读者更容易理解?

请说清楚

 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])

  1. 累加器是一个数组。 你重新分配它,给它一个新数组,其中包含你在循环开始时拥有的项和要添加的数组项的项。 正如评论中所说, acc.concat返回一个新数组,其中包含传入参数的 arrays 的项目。 请参阅https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/concat

  2. 您需要在每个循环结束时返回累加器,以便在下一个循环中考虑新值。

  3. Javascript 递归数组展平

  1. acc = acc.concat(flatWithRec(item)); 为什么累加器被重新分配? 如何减少 function? 为什么在这里使用concat

累加器 ( acc ) 是一个 function 参数,可以重新分配,尽管这样做不是一个好习惯。 Concat 结合两个项目(数组或其他),并返回一个新数组,因此您需要将其分配给acc作为当前循环的结果。

  1. return acc; 为什么 acc 被退回? 每次调用 function 时,它是一个新的平面阵列吗?

累加器保存减少项目的当前 state,在您的情况下,每个循环后的当前平面数组。 您需要将其返回,以便下一个循环可以继续累积。

  1. 有没有办法仍然使用递归并使读者更容易理解?

我对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 (请参阅最后使用pushspread的解决方案)

return acc; 为什么acc被退回? 每次调用 function 时,它是一个新的平面阵列吗?

如前所述,您需要从回调中返回正确的 state。 是的,在每次迭代期间,都会创建一个新数组(这不是那么高效,请参阅最后的解决方案)

有没有办法仍然使用递归并让读者更容易理解?

我不知道对读者来说更容易,但这是我使用=> functionsspread的解决方案。

 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM