![](/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.