簡體   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