[英]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
):
reduceFn(accumulatedValue = [[]], item = 'dog'): [[], ['dog']]
mapFn(e = []): [['dog']]
mapFn(e = []): [['dog']]
['dog'].concat([]): ['dog']
['dog'].concat([]): ['dog']
return [[]].concat([['pig']])
return [[]].concat([['pig']])
reduceFn(accumulatedValue = [[], ['dog']], item = 'pig'): [[], ['dog'], ['pig'], ['pig', 'dog']]
mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]
mapFn(e = [[], ['dog']]): [['pig'], ['pig', 'dog']]
['pig'].concat([]): ['pig']
['pig'].concat([]): ['pig']
['pig'].concat(['dog']): ['pig', 'dog']
['pig'].concat(['dog']): ['pig', 'dog']
return [[], ['dog']].concat([['pig'], ['pig', 'dog']])
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.