简体   繁体   English

concat + apply到底是做什么来使数组变平?

[英]What exactly is concat + apply doing to flatten an array?

I've basically memorized this [].concat.apply([], a) to flatten an array that isn't deeply nested but I don't entirely understand how it works. 我基本上已经记住了这个[].concat.apply([], a)来使未深度嵌套的数组变平,但是我不完全理解它是如何工作的。 For instance, where does apply comes into this? 例如,这apply于哪里?

Is it more efficient than arr.reduce((x,y) => [...x,...y]) ? 它比arr.reduce((x,y) => [...x,...y])吗?

There are a couple of aspects to this: 有两个方面:

concat flattens (to one level) arrays you pass into it, including only their elements in the resulting array: concat平(到一个级别)数组,将它们传递到其中,仅包括它们在结果数组中的元素:

 console.log([1, 2, 3].concat(4, 5, [6, 7, 8])); 

Notice how the array at the end was flattened. 注意最后的数组是如何变平的。

The apply is Function.prototype.apply : You can use it to call a function specifying what this should be and providing the arguments for the function as an array. applyFunction.prototype.apply :您可以使用它来调用一个函数, this函数指定应为的内容并将该函数的参数作为数组提供。 That last bit is critical: The array's elements are passed to concat as discrete arguments, and if any of those are arrays, concat extracts their content. 最后一点是关键:数组的元素传递给concat为离散变量,而如果这些都阵列, concat提取它们的内容。 So 所以

let a = [[1, 2, 3], 4, 5, [6, 7, 8]];
a = [].concat.apply([], a);
//  ^^--- (1)       ^^--- (2)

...calls concat with this being array (2) above, passing in the arguments [1, 2, 3] , 4 , 5 , and [6, 7, 8] . ...调用concatthis感阵列(2)中,通过在参数[1, 2, 3] 45 ,和[6, 7, 8] (Array (1) is only used to get concat , then thrown away.) (数组(1)仅用于获取concat ,然后将其丢弃。)

[].concat.apply([], a) is a bit wasteful (it creates two throw-away arrays, both of the ones indicated above), though it's not likely to matter; [].concat.apply([], a)有点浪费(它创建两个抛出的数组,上面都指出了这两个数组),尽管这不太可能。 really it should be `Array.prototype.concat.apply([], although that still creates and throws away one of them. (Obviously, you'd tuck that away in a reusable function so you don't have to type that out every time.) 确实应该是`Array.prototype.concat.apply([],尽管它仍然会创建并丢弃其中一个。(显然,您会将其塞入可重用的函数中,因此不必键入它每次。)

But in modern JavaScript you may want to use flat instead, with a polyfill if necessary: 但是在现代JavaScript中,您可能需要改用flat ,并在必要时使用polyfill:

 console.log( [ [1, 2, 3], 4, 5, [6, 7, 8] ].flat() ); 

The above works on up-to-date versions of Chrome, Firefox, and Safari, but again you can use a polyfill to use it on other browsers. 上面的代码适用于最新版本的Chrome,Firefox和Safari,但是您仍然可以使用polyfill在其他浏览器上使用它。

Note that flat optionally does recursive flattening. 请注意, flat可选地进行递归展平。 By default it does just one level (like concat ), but if you specify a depth argument, you can go deeper (you can use Infinity to handle all levels). 默认情况下,它仅执行一个级别(如concat ),但是如果指定depth参数,则可以更深入(可以使用Infinity来处理所有级别)。

The apply call is equivalent to using spread syntax: apply调用等效于使用传播语法:

[].concat.apply([], a)
[].concat(...a)

It simply concatenates an empty array with all the values of a , passing muliple arguments to concat . 它只是用串接的所有值空数组a ,传递muliple参数concat It constructs a new array in a single step, which is more efficient than your reduce solution that creates lots of intermediate results. 它只需一步就可以构造一个新数组,这比创建大量中间结果的化reduce解决方案效率更高。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM