繁体   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