最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - What exactly is concat + apply doing to flatten an array? - Stack Overflow

programmeradmin3浏览0评论

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. For instance, where does apply es into this?

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

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. For instance, where does apply es into this?

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

Share Improve this question edited Jan 24, 2019 at 17:01 Liam 29.8k28 gold badges138 silver badges200 bronze badges asked Jan 24, 2019 at 16:58 CurlyCurly 1095 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 11

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:

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. 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. 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]. (Array (1) is only used to get concat, then thrown away.)

[].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; 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.)

But in modern JavaScript you may want to use flat instead, with a polyfill if necessary:

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.

Note that flat optionally does recursive flattening. 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).

The apply call is equivalent to using spread syntax:

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

It simply concatenates an empty array with all the values of a, passing multiple arguments to concat. It constructs a new array in a single step, which is more efficient than your reduce solution that creates lots of intermediate results.

发布评论

评论列表(0)

  1. 暂无评论