![](/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.