简体   繁体   English

Javascript 嵌套函数使用 Reduce、Map 和 Concat 与数组的组合

[英]Javascript Nested Functions Using Combination of Reduce, Map and Concat with an Array

Can someone please explain to me how this code:有人可以向我解释一下这段代码如何:

const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
console.log(powerset(["dog", "pig"]));

returns this array output in the console?在控制台中返回这个数组 output?

0: []
1: ["dog"]
2: ["pig"]
3: (2) ["pig", "dog"]
length: 4

The point was to take the elements from an array and return all of the possible combinations of those elements.关键是从数组中获取元素并返回这些元素的所有可能组合。 I understand the reduce function, concatenating and mapping, but I'm having a hard time comprehending how these nested functions are being applied and in what order to get this output.我了解减少 function、连接和映射,但我很难理解这些嵌套函数是如何应用的,以及以什么顺序得到这个 output。 Anyone able to walk me through what is happening on each run-through of the function(s)?任何人都可以带我了解每次运行功能时发生的事情吗?

First off, take the constant and turn it into a function:首先,取常数并将其转换为 function:

function powerset(arr){
  return arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]])
}

We know that reduce will loop through the elements and put them into a , the accumulator.我们知道reduce会循环遍历元素并将它们a累加器中。 Meanwhile, it will also do 'something' with v , the value.同时,它也会对价值v做“一些事情”。 So, let's dig deeper:所以,让我们深入挖掘:

a.concat(a.map(r => [v].concat(r)))

Here, it takes the accumulator and adds an array to it.在这里,它接受累加器并向其中添加一个数组。 But what is the array?但是数组是什么? This is:这是:

a.map(r => [v].concat(r))

Now we can see that it takes each element of a and essentially pushes v , the value, into it.现在我们可以看到它获取了a的每个元素,并且本质上将v (值)推入其中。

Working backwards, now we can see that a starts off as [[]] , then gets merged with the array that is outputted from a.map(r => [v].concat(r)) .向后工作,现在我们可以看到a[[]]开始,然后与从a.map(r => [v].concat(r))输出的数组合并。 That simply happens to be the first element of arr .这恰好是arr的第一个元素。 So, it turns to [[], [first_element]] .所以,它转向[[], [first_element]]

Repeating this, we can see that each time, it takes an element, adds it to each subarray in the accumulator, takes all of those arrays, and adds it back to the accumulator.重复此操作,我们可以看到,每次它获取一个元素,将其添加到累加器中的每个子数组,获取所有这些 arrays,并将其添加回累加器。 So now, you have all sets both with the example element el , AND without the example element el .所以现在,您拥有所有带有示例元素el和没有示例元素el的集合。 Repeating, you have all possible combinations.重复,你有所有可能的组合。

It might help to view the code as separate functions:将代码视为单独的函数可能会有所帮助:

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);
  }
}

The execution of arr.reduce looks like this (read as call(): result ): arr.reduce的执行看起来像这样(读作call(): result ):

  1. reduceFn(accumulatedValue = [[]], item = 'dog'): [[], ['dog']]
    • accumulatedValue.map: mapFn(e = []): [['dog']]累积值.map: mapFn(e = []): [['dog']]
      • return [item].concat: ['dog'].concat([]): ['dog']返回 [item].concat: ['dog'].concat([]): ['dog']
    • return accumulatedValue.concat: return [[]].concat([['pig']])返回累积值.concat: return [[]].concat([['pig']])
  2. reduceFn(accumulatedValue = [[], ['dog']], item = 'pig'): [[], ['dog'], ['pig'], ['pig', 'dog']]
    • accumulatedValue.map: mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]累积值.map: mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]
      • return [item].concat: ['pig'].concat([]): ['pig']返回 [item].concat: ['pig'].concat([]): ['pig']
      • return [item].concat: ['pig'].concat(['dog']): ['pig', 'dog'] return [item].concat: ['pig'].concat(['dog']): ['pig', 'dog']
    • return accumulatedValue.concat: return [[], ['dog']].concat([['pig'], ['pig', 'dog']])返回累积值.concat: return [[], ['dog']].concat([['pig'], ['pig', 'dog']])

Answered, Here was the original code: along with my new understanding of what's going on:回答,这是原始代码:以及我对正在发生的事情的新理解:

const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
console.log(powerset(["dog", "pig"]));

1.) The reduce function is taking in the accumulator a , which starts with our initializer [[]] , and the first value v from the array powerset , which is dog . 1.) reduce function 接收累加器a ,它以我们的初始化程序[[]]开头,以及数组powerset中的第一个值v ,即dog

2.) When we map through a , our first value of r is the empty array with subarray, [[]] . 2.) 当我们 map 通过a时,我们的第一个值r是带有子数组[[]]的空数组。 When you do [dog].concat([[]]) , you end up with just [dog] .当您执行[dog].concat([[]])时,您最终只会得到[dog]

3.) Then, you have a.concat(dog) , so you end up with [[], [dog]] . 3.) 然后,你有a.concat(dog) ,所以你最终得到[[], [dog]] Your new accumulator or a value is now [[], [dog]] .您的新累加器或值现在a [[], [dog]]

4.) Next loop of the reduce function, accumulator a is [[], [dog]] , and v is the second item in our powerset array, pig . 4.) reduce function 的下一个循环,累加器a[[], [dog]]v是我们的powerset数组pig中的第二项。

5.) Again, map through a . 5.) 同样,map a . First loop will be pig.concat([]) .第一个循环是pig.concat([]) You will just get [pig] .你只会得到[pig]

6.) Next loop will be pig.concat([dog]) , so you get [pig, dog] . 6.) 下一个循环是pig.concat([dog]) ,所以你得到[pig, dog]

7.) Now, perform the a.concat again. 7.) 现在,再次执行a.concat Because our new a was [[], [dog]] , we are now adding our two new results to get [[], [dog], [pig], [pig, dog]] .因为我们的新a[[], [dog]] ,我们现在添加两个新结果以获得[[], [dog], [pig], [pig, dog]]

That is how we end up with all of the different combinations of "pig, dog".这就是我们最终得到“猪,狗”的所有不同组合的方式。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 javascript reduce 使用 reduce/map 函数将平面数组转换为嵌套数组 - javascript reduce to convert a flat array to a nested array using reduce/map functions 使用 map 从嵌套数组打印,在 javascript 中减少和过滤 - Print from nested array using map, reduce and filter in javascript 嵌套对象数组上的 Javascript reduce 和 map - Javascript reduce and map on nested array of objects 嵌套数组的递归方法,而不使用JavaScript中的.concat或.reduce - recursive approach to nested arrays without using .concat or .reduce in JavaScript 在单个 const 中使用 Object.keys()、map()、...Array()、reduce() 和 concat() - Using Object.keys(), map(), …Array(), reduce() and concat() in a single const 在 javascript 中将 map\reduce 与嵌套元素一起使用 - Using map\reduce with nested elements in javascript 在处理深度嵌套的对象数组时,在 map() 中使用多个 reduce() 函数的替代方法? - Alternatives to using multiple reduce() functions inside a map() when handling deeply nested array of objects? 我需要一些帮助来理解这种方法组合(reduce、concat 和 map) - I need some help to understand this combination of methods (reduce, concat and map) 使用嵌套键减少 Javascript 对象数组 - Reduce a Javascript Array of Objects using nested keys 在JavaScript中使用带有reduce的map来过滤数组中的对象 - Using map with reduce in javascript to filter objects in an array
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM