![](/img/trans.png)
[英]javascript reduce to convert a flat array to a nested array using reduce/map functions
[英]Javascript Nested Functions Using Combination of Reduce, Map and Concat with an Array
有人可以向我解釋一下這段代碼如何:
const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
console.log(powerset(["dog", "pig"]));
在控制台中返回這個數組 output?
0: []
1: ["dog"]
2: ["pig"]
3: (2) ["pig", "dog"]
length: 4
關鍵是從數組中獲取元素並返回這些元素的所有可能組合。 我了解減少 function、連接和映射,但我很難理解這些嵌套函數是如何應用的,以及以什么順序得到這個 output。 任何人都可以帶我了解每次運行功能時發生的事情嗎?
首先,取常數並將其轉換為 function:
function powerset(arr){
return arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]])
}
我們知道reduce
會循環遍歷元素並將它們a
累加器中。 同時,它也會對價值v
做“一些事情”。 所以,讓我們深入挖掘:
a.concat(a.map(r => [v].concat(r)))
在這里,它接受累加器並向其中添加一個數組。 但是數組是什么? 這是:
a.map(r => [v].concat(r))
現在我們可以看到它獲取了a
的每個元素,並且本質上將v
(值)推入其中。
向后工作,現在我們可以看到a
從[[]]
開始,然后與從a.map(r => [v].concat(r))
輸出的數組合並。 這恰好是arr
的第一個元素。 所以,它轉向[[], [first_element]]
。
重復此操作,我們可以看到,每次它獲取一個元素,將其添加到累加器中的每個子數組,獲取所有這些 arrays,並將其添加回累加器。 所以現在,您擁有所有帶有示例元素el
和沒有示例元素el
的集合。 重復,你有所有可能的組合。
將代碼視為單獨的函數可能會有所幫助:
function powerset(arr) {
const initial = [[]];
return arr.reduce(reduceFn, initial);
function reduceFn(accumulatedValue, item) {
// item will be "dog" or "pig"
// accumulatedValue will start as [[]] and be equal to the result of the previous call of reduceFn by .reduce()
const concatenatedAccumulation = accumulatedValue.map(function mapFn(e) {
return [item].concat(e) // i.e. [item, ...e]
});
return accumulatedValue.concat(concatenatedAccumulation);
}
}
arr.reduce
的執行看起來像這樣(讀作call(): result
):
reduceFn(accumulatedValue = [[]], item = 'dog'): [[], ['dog']]
mapFn(e = []): [['dog']]
['dog'].concat([]): ['dog']
return [[]].concat([['pig']])
reduceFn(accumulatedValue = [[], ['dog']], item = 'pig'): [[], ['dog'], ['pig'], ['pig', 'dog']]
mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]
['pig'].concat([]): ['pig']
['pig'].concat(['dog']): ['pig', 'dog']
return [[], ['dog']].concat([['pig'], ['pig', 'dog']])
回答,這是原始代碼:以及我對正在發生的事情的新理解:
const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
console.log(powerset(["dog", "pig"]));
1.) reduce function 接收累加器a
,它以我們的初始化程序[[]]
開頭,以及數組powerset
中的第一個值v
,即dog
。
2.) 當我們 map 通過a
時,我們的第一個值r
是帶有子數組[[]]
的空數組。 當您執行[dog].concat([[]])
時,您最終只會得到[dog]
。
3.) 然后,你有a.concat(dog)
,所以你最終得到[[], [dog]]
。 您的新累加器或值現在a
[[], [dog]]
。
4.) reduce function 的下一個循環,累加器a
是[[], [dog]]
, v
是我們的powerset
數組pig
中的第二項。
5.) 同樣,map a
. 第一個循環是pig.concat([])
。 你只會得到[pig]
。
6.) 下一個循環是pig.concat([dog])
,所以你得到[pig, dog]
。
7.) 現在,再次執行a.concat
。 因為我們的新a
是[[], [dog]]
,我們現在添加兩個新結果以獲得[[], [dog], [pig], [pig, dog]]
。
這就是我們最終得到“豬,狗”的所有不同組合的方式。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.