首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >[].concat(...arr)与[...arr]有何不同?

[].concat(...arr)与[...arr]有何不同?
EN

Stack Overflow用户
提问于 2022-10-21 19:50:13
回答 3查看 61关注 0票数 0

我正在通过免费JavaScript课程,我偶然发现了这个“压路机”挑战。来自python的我非常喜欢一行解决方案,所以我成功地为这个挑战编写了一个:

代码语言:javascript
复制
function steamrollArray(arr) {
  return Array.isArray(arr) ? [].concat(...arr.map(steamrollArray)) : arr;
}

steamrollArray([1, [2], [3, [[4]]]]) // returns [1, 2, 3, 4]

其目标基本上是使任意深度的数组变平。但让我感到困惑的是,为什么看似相似的代码表现得非常不同(对JavaScript来说仍是新生事物)。我在一开始写的东西不起作用,但我通过试用获得的代码(主要是错误)起作用了:

代码语言:javascript
复制
[...arr.map(steamrollArray)] // this doesn't work, returns an unchanged array

[].concat(...arr.map(steamrollArray)) // this works, returns a flat array

这对我来说很奇怪,因为递归的“展开”意味着它应该是相反的。

代码语言:javascript
复制
[...arr.map(steamrollArray)] 
[1, ...[2], ...[3, ...[...[4]]]] // this should work

[].concat(...arr.map(steamrollArray))
[].concat(...[1, [].concat(...[2]), [].concat(...[3, [].concat(...[].concat(...[4]))])]) // what 'is going on'

有人能解释一下这种行为吗?

EN

回答 3

Stack Overflow用户

发布于 2022-10-21 19:55:57

来自MDN的报价

然后,对于每个参数,它的值将连接到数组中-对于普通对象或原语,参数本身将成为最终数组的一个元素;用于数组.,参数的每个元素将独立地添加到最终数组中。

您可以在下面观察到这种行为;尽管第二个调用使用了一个数组,但两者都为我们提供了[1, 2, 3, 4, 5, 6]

代码语言:javascript
复制
console.log([1, 2, 3].concat(4, 5, 6));
console.log([1, 2, 3].concat([4, 5, 6]));

如果要连接整个数组,则必须将其包装在另一个数组中:

代码语言:javascript
复制
console.log([1, 2, 3].concat([[4, 5, 6]])); // [1, 2, 3, [4, 5, 6]]

那么这与你的问题有什么关系呢?好吧..。如果我们有一个类似于[1, 2, [3, 4], 5, [6]]的数组,并将其扩展到concat中,我们将得到如下所示:

代码语言:javascript
复制
console.log([].concat(1, 2, [3, 4], 5, [6]));

..。本质上是“平缓”它的一个层次。您的函数是递归的,因此它像这样平放数组,直到它完全平坦。

票数 1
EN

Stack Overflow用户

发布于 2022-10-21 19:59:05

Array.prototype.concat的参数(如果它们是数组的话)本质上被平放到生成的数组中。

代码语言:javascript
复制
[2].concat(3, [4, 5])

[2, 3, 4, 5]检查结果。类似的

代码语言:javascript
复制
[].concat(3, [4, 5])

[3, 4, 5]检查结果。

但是,将数组扩展到另一个数组并不会对扩展数组的每个元素执行这样的平坦处理。

代码语言:javascript
复制
const arr = [3, [4, 5]];
const newArr = [...arr];

获取arr的每个元素,并将其放入一个新的数组中--但就这样,给出[3, [4, 5]] --原始数组的相同值,但在不同的数组中。

关于您问题中的代码:

代码语言:javascript
复制
[...arr.map(steamrollArray)]

失败,因为是steamrollArray完成了扁平化操作--但是您还需要将每个返回的数组都压平。例如,如果您传入[[1, 2], [3, [4, 5]]]

代码语言:javascript
复制
[...[[1, 2], [3, [4, 5]]].map(steamrollArray)]
[...[[1, 2], [3, 4, 5]]]

这不会使顶层变平。但是[].concat(...arr.map(steamrollArray))可以工作,因为concat (肤浅地)将每个数组参数都平放到结果中。

票数 1
EN

Stack Overflow用户

发布于 2022-10-21 20:08:18

所以其他人回答了你的问题,但是这里有一些简化的代码

代码语言:javascript
复制
const steamrollArray1 = arr => Array.isArray(arr) ? [].concat(...arr.map(steamrollArray1)) : arr;

const steamrollArray2 = arr => Array.isArray(arr) ? arr.flat(Infinity) : arr;

console.log(
  steamrollArray1([1, [2], [3, [[4]]]])
); // returns [1, 2, 3, 4]

console.log(
  steamrollArray2([1, [2], [3, [[4]]]])
); // returns [1, 2, 3, 4]

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74158560

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档