Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 我需要一些帮助来理解这种方法的组合(reduce、concat和map)_Javascript_Ecmascript 6 - Fatal编程技术网

Javascript 我需要一些帮助来理解这种方法的组合(reduce、concat和map)

Javascript 我需要一些帮助来理解这种方法的组合(reduce、concat和map),javascript,ecmascript-6,Javascript,Ecmascript 6,我正在学习ES6,我正在努力学习这一行代码。我知道我正在失去一些东西,我只是不明白到底发生了什么 守则: const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); console.log(powerset([1, 2, 3]));

我正在学习ES6,我正在努力学习这一行代码。我知道我正在失去一些东西,我只是不明白到底发生了什么

守则:

const powerset = arr => 
                arr.reduce((a, v) => 
                    a.concat(a.map(r => 
                        [v].concat(r))), [[]]);

console.log(powerset([1, 2, 3]));
输出:

[[], [1], [2], [2, 1], [3], [3, 1], [3, 2], [3, 2, 1]]
我在这里看到了什么

第一个
concat
将在“主数组”中连接每个
map
的返回,这个将
r
的值与
v
的值连接,我相信
r
等于
a

基于此,我的理解是(我知道我错了,但我不知道为什么),它应该是这样工作的:

在第一个“级别”
a
是一个空数组,并且
v
等于1,因此第一个值应该是
[1]
,而不是
[]
,因为
r
正在与
v
串联;在第二个“级别”
a
等于1,而
v
等于2,什么将返回
[2,1]
,而在第三个“级别”中,返回将是
[3,2,1]
,因为
v
等于3,而
a
将返回
[2,1]

正如我之前所说,我知道我错了,但我就是看不出我在这里失去了什么。我做了研究,也做了很多实验,但都没有得到


这段代码到底是如何工作的?

让我们先稍微修改一下格式:

arr.reduce(
  (a, v) => a.concat(a.map(r => [v].concat(r))),
  [[]]
)
因此,
reduce
[[]]
作为起始值,回调函数返回与其他内容连接的列表。到目前为止,返回值是
[[],…]
是合理的,然后,它是附加了附加值的起始值

将三个值传递到
powerset
,此
reduce
过程将进行三次迭代

现在,每个回合都有什么连接到列表中

a.map(r => [v].concat(r))
a
是它开始并将返回的列表,
v
arr
中的当前值,该列表首先被传递到
powerset
r
是当前
a
中的每个值

因此,在第一次迭代中,
a
[[]]
,因此
r
将是
[]
一次,而
v
1

  [[]].map(_ => [1].concat([]))
→ [[]].map(_ => [1])  // [1].concat([]) is [1]
→ [[1]]
因此,第一个
map
操作返回
[[1]]

  (a, _) => a.concat([[1]])
→ (_, _) => [[], [1]]
因此,您确实看到了输出的开始。在下一次迭代中,
a
[[],[1]]
v
2

  a        .map(r => [v].concat(r))
→ [[], [1]].map(r => [2].concat(r))  // two mappings here:
  → []  → [2].concat([])             // [2]
  → [1] → [2].concat([1])            // [2, 1]
→ [[2], [2, 1]]
因此:


您可以自己计算第三次迭代。

FWIW,即使是经验丰富的人也必须眯着眼睛才能计算出来……将它分成几个小部分,并计算出传递给每个嵌套函数的确切内容,以及该函数反过来产生的内容。试着将
console.log(“adding”,v,“to”,JSON.stringify(a))
reduce
回调中,这会让你犯两个错误:
a
从来都不是空数组(如果它是空数组,它就不会工作),它从
[[]]
开始。
r
a
的元素,而第一个
r
实际上是一个空数组。因为您从不替换初始值[]的第一个索引。concat只是将数组连接在一起。现在已经非常清楚了。非常感谢你。这让我发疯,哈哈。但看到你的解释,我相信我明白我现在失去了什么。事实上,这是两件事,我没有考虑
a
的第一个索引中的空数组,也没有考虑应用
map
时的整个数组,只考虑当前值。但现在一切都清楚了。再次感谢你。
  (a, _) => a.concat([[2], [2, 1]])
→ (_, _) => [[], [1], [2], [2, 1]]