簡體   English   中英

Javascript 嵌套函數使用 Reduce、Map 和 Concat 與數組的組合

[英]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 ):

  1. reduceFn(accumulatedValue = [[]], item = 'dog'): [[], ['dog']]
    • 累積值.map: mapFn(e = []): [['dog']]
      • 返回 [item].concat: ['dog'].concat([]): ['dog']
    • 返回累積值.concat: return [[]].concat([['pig']])
  2. reduceFn(accumulatedValue = [[], ['dog']], item = 'pig'): [[], ['dog'], ['pig'], ['pig', 'dog']]
    • 累積值.map: mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]
      • 返回 [item].concat: ['pig'].concat([]): ['pig']
      • return [item].concat: ['pig'].concat(['dog']): ['pig', 'dog']
    • 返回累積值.concat: 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM