我基本上已经记住了这个[].concat.apply([], a)
来使未深层嵌套的数组变平,但是我不完全理解它是如何工作的。例如,apply
从何而来?
它比arr.reduce((x,y) => [...x,...y])
更有效率吗?
答案 0 :(得分:4)
这有两个方面:
concat
将传入的数组展平(到一个级别),仅包括结果数组中的元素:
console.log([1, 2, 3].concat(4, 5, [6, 7, 8]));
注意最后的数组是如何变平的。
apply
是Function.prototype.apply
:您可以使用它来调用一个函数,该函数指定应为this
,并将该函数的参数作为数组提供。最后一点很关键:将数组的元素作为离散参数传递给concat
,如果那些中的任何一个是数组,则concat
将提取其内容。所以
let a = [[1, 2, 3], 4, 5, [6, 7, 8]];
a = [].concat.apply([], a);
// ^^--- (1) ^^--- (2)
...调用concat
,其中this
在上面的数组(2)中,并传入参数[1, 2, 3]
,4
,5
和{{ 1}}。 (数组(1)仅用于获取[6, 7, 8]
,然后扔掉。)
concat
有点浪费(它创建两个扔掉的数组,两个都在上面指出),尽管这不太可能。确实应该是`Array.prototype.concat.apply([],尽管它仍然会创建并丢弃其中一个。(显然,您会将其塞入可重用的函数中,因此不必键入它每次。)
但是在现代JavaScript中,您可能需要改用flat
,并在必要时使用polyfill:
[].concat.apply([], a)
以上内容适用于最新版本的Chrome,Firefox和Safari,但是您仍然可以使用polyfill在其他浏览器上使用它。
请注意,console.log(
[
[1, 2, 3],
4, 5,
[6, 7, 8]
].flat()
);
可以进行递归展平。默认情况下,它仅执行一个级别(如flat
),但是如果指定 depth 参数,则可以更深入(可以使用Infinity来处理所有级别)。
答案 1 :(得分:3)
apply
调用等效于使用扩展语法:
[].concat.apply([], a)
[].concat(...a)
它简单地将一个空数组与所有a
的值连接起来,将多个参数传递给concat
。它只需一步就可以构造一个新数组,这比创建大量中间结果的reduce
解决方案效率更高。