DEV Community

Samantha Ming
Samantha Ming

Posted on

2 Ways to Merge Arrays in JavaScript

Code Tidbit by SamanthaMing.com

Here are 2 ways to combine your arrays and return a NEW array. I like using the Spread operator. But if you need older browser support, you should use Concat.



// 2 Ways to Merge Arrays 

const cars = ['๐Ÿš—', '๐Ÿš™'];
const trucks = ['๐Ÿšš', '๐Ÿš›'];

// Method 1: Concat 
const combined1 = [].concat(cars, trucks);

// Method 2: Spread
const combined2 = [...cars, ...trucks];

// Result
// [ '๐Ÿš—', '๐Ÿš™', '๐Ÿšš', '๐Ÿš›' ]


Enter fullscreen mode Exit fullscreen mode

Alternative Concat Syntax

Alternatively, you can also write the concat method, in this regard:



const cars = ['๐Ÿš—', '๐Ÿš™'];
const trucks = ['๐Ÿšš', '๐Ÿš›'];

const combined = cars.concat(trucks);
// [ '๐Ÿš—', '๐Ÿš™', '๐Ÿšš', '๐Ÿš›' ]

console.log(cars); // ['๐Ÿš—', '๐Ÿš™'];
console.log(trucks); // ['๐Ÿšš', '๐Ÿš›'];


Enter fullscreen mode Exit fullscreen mode

As you can see, this way of writing it doesn't manipulate or change the existing array.

Which one should I pick?

Let's list out both versions, so you can see it in comparison.



// Version A:
const combinedA = [].concat(cars, trucks);

// Version B:
const combinedB = cars.concat(trucks);


Enter fullscreen mode Exit fullscreen mode

So now the question is, which one should I pick ๐Ÿค”. I prefer Version A because I think the intention is a lot more clear. Just by looking at it, I know I'm creating a new array and I'm not manipulating the existing array. Whereas if I look at Version B, it appears like I'm adding the trucks array to the cars array, and it doesn't seem obvious to me that the cars array isn't being changed. But, maybe that's just me. I'd be curious to know what you think?

Since I don't really have a substantial reason besides aesthetics, I think you and your team should stick with whatever you choose ๐Ÿ‘

Difference between Spread vs Concat

I prefer using spread, because I find it more concise and easier to write. BUT, there are still benefits of using concat.

Spread is fantastic when you know beforehand that you're dealing with arrays. But what happens when the source is something else, like a string. And you want to add that string to the array. Let's walk through an example.

Example: Dealing with an arbitrary argument

Let's say this is the outcome we want:



[1,2,3,'random']


Enter fullscreen mode Exit fullscreen mode

A. Using Spread

And if we follow the pattern we've been using and used the spread operator. Here's what happens:



function combineArray(array1, array2) {
  return [...array1, ...array2];
}

const isArray = [1,2,3];
const notArray = 'random';

combineArray(isArray, notArray);
// ๐Ÿ˜ฑ [ 1, 2, 3, 'r', 'a', 'n', 'd', 'o', 'm' ]


Enter fullscreen mode Exit fullscreen mode

โ˜๏ธ If we spread our string, it will split the word into separate letters. So it doesn't achieve the result we want.

B. Using Concat

BUT, if we follow the concat pattern that we've been doing. Here's what happens:



function combineArray(array1, array2) {
  return [].concat(array1, array2);
}

const isArray = [1,2,3];
const notArray = 'random';

combineArray(isArray, notArray);
// โœ…  [ 1, 2, 3, 'random' ]


Enter fullscreen mode Exit fullscreen mode

โ˜๏ธ Excellent! We get the result we want.

I know some of you are like, duh! I'll just write some conditional to make sure what I'm passing is an array and execute accordingly. Sure that'd work too. Or just write less code and use concat and be done with ๐Ÿ˜‚

Verdict

So here's the quick rule. If you know you're dealing with arrays, use spread. But if you might be dealing with the possibility with a non-array, then use concat to merge an array ๐Ÿ‘

Anyways I just want to point that out, so you can use the most appropriate method depending on the problem you're trying to solve ๐Ÿ‘

Merge Array with Push ๐Ÿค”

Some of you are asking, hey, can't I also use push to merge an array. And yes, you sure can! But when you use push, it manipulates or changes the existing array. It does NOT create a new array. So depending on what you're trying to do. Make sure you keep that in mind.



const cars = ['๐Ÿš—', '๐Ÿš™'];
const trucks = ['๐Ÿšš', '๐Ÿš›'];

const combined = cars.push(...trucks);

console.log(combined); // 4
// โ˜when you use push, it returns the LENGTH of the combined array

console.log(cars); // [ '๐Ÿš—', '๐Ÿš™', '๐Ÿšš', '๐Ÿš›' ]
console.log(trucks); // ['๐Ÿšš', '๐Ÿš›']


Enter fullscreen mode Exit fullscreen mode

Also, when you're trying to push an array to another array. You will need to spread it, otherwise, you will end up getting a nested array. Of course, unless that's what you wanted ๐Ÿ˜œ



const cars = ['๐Ÿš—', '๐Ÿš™'];
const trucks = ['๐Ÿšš', '๐Ÿš›'];

cars.push(trucks);
// ๐Ÿ˜ฑ cars: [ '๐Ÿš—', '๐Ÿš™', [ '๐Ÿšš', '๐Ÿš›' ] ]

cars.push(...trucks);
// โœ… cars: [ '๐Ÿš—', '๐Ÿš™', '๐Ÿšš', '๐Ÿš›' ]

Enter fullscreen mode Exit fullscreen mode




Browser Support

Spread was introduced in ES6, so all modern browser supports it. Except for the "I'm too cool" Internet Explorer - no support there ๐Ÿ˜•. So if you need IE support, you want to use concat instead or use a compiler like Babel.

Resources


Thanks for reading โค
Say Hello! Instagram | Twitter | Facebook | Medium | Blog

Top comments (19)

Collapse
ย 
thomas_graf profile image
Thomas Graf โ€ข

Maybe it's a little bit longer, but you don't have to create an array just to use the prototypes concat method.

Instead of

[].concat([1,2],[3,4])

you could also write that one:

Array.prototype.concat([1,2],[3,4])
Collapse
ย 
thomas_graf profile image
Thomas Graf โ€ข

Just for fun I tried it on jsperf and the first one is way faster. Never thought that. But it's probably just a micro optimization.

jsperf.com/empty-array-conact-vs-p...

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

nice, thanks for sharing that ๐Ÿ‘

Collapse
ย 
qm3ster profile image
Mihail Malo โ€ข

The "A. Using Spread" example fails to demonstrate the error, since it says return [...array1, array2] instead of return [...array1, ...array2] (it doesn't actually spread the string)
Instead it demonstrates the happy path of "immutably pushing" the string.

I firmly believe concat is dangerous and should only be used with arrays, not loose elements. Because your loose element will end up being an array someday, and you will SUFFER.
And on the other hand, it doesn't work on arraylikes:

[].concat([document.querySelector('body')],document.querySelectorAll('*')) // nope

;[document.querySelector('body'), ...document.querySelectorAll('*')] // yep
Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

Oops, thatโ€™s a typo ๐Ÿ˜ฌ let me fix that ๐Ÿ˜ฐ

Collapse
ย 
michelloworld profile image
Mic โ€ข

From example "A. Using Spread"

I think forgot put "..." before "array2"

function combineArray(array1, array2) {
  return [...array1, array2]; // <-------------- HERE
}

const isArray = [1,2,3];
const notArray = 'random';

combineArray(isArray, notArray);
// ๐Ÿ˜ฑ [ 1, 2, 3, 'r', 'a', 'n', 'd', 'o', 'm' ]

sorry if i'm wrong.

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

Ahhhh my mistake ๐Ÿ˜ฑ Thank you for letting me know ๐Ÿ‘

Collapse
ย 
agronick profile image
Kyle Agronick โ€ข โ€ข Edited

Surprisingly concat is way faster. Doing any type of spread is 91% slower. jsperf.com/concat-vs-spreader/1

Edit: Actually, it seems to depend on the size of the array. With 10 elements in each array spread is faster. With 100 elements in each array spread is about 75% slower.

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

Interesting, thanks for writing out the test! Good to keep in mind if you need to optimize the code. But I wonder as spread become more popular, if the browser will start optimizing it ... maybe concat is faster because itโ€™s been around longer and the browser is deciphering it ๐Ÿค”

Collapse
ย 
agronick profile image
Kyle Agronick โ€ข

I wondered that too. You would think it would just call concat internally. I'm not sure what would cause the huge difference.

Collapse
ย 
itachiuchiha profile image
Itachi Uchiha โ€ข โ€ข Edited
[...['a', 'l'], ...['i', ...['ran', ...[...['d', ...['o'], ...['m']]]]]]

I like spread parameters :)

Thanks.

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

Same here! But thatโ€™s some crazy nesting you have there ๐Ÿ˜‚

Collapse
ย 
lexlohr profile image
Alex Lohr โ€ข

To emulate spread parameters in older Javascript, you can use cars.push.apply(cars, trucks). However, that doesn't read half as nice.

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

older support is definitely very important, especially if all your clients refuse to upgrade to newer browsers ๐Ÿ˜

Collapse
ย 
mak12776 profile image
Mohammad Amin Khakzadan โ€ข

javascript looks awesome, it's like that you are playing a game when you are programming in that. but that's not good. check jsfuck.com/.

Collapse
ย 
olivermensahdev profile image
Oliver Mensah โ€ข

I also think the same as it doesn't seem obvious to me that the cars array isn't being changed. I enjoy your explanations

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

Awesome, glad you found it helpful ๐Ÿ™‚๐Ÿ‘

Collapse
ย 
anortef profile image
Adriรกn Norte โ€ข

I very much prefer the [].concat way because it's extremely obvious what is going on.

Collapse
ย 
samanthaming profile image
Samantha Ming โ€ข

I learned that syntax from Object.assign. I just notice how much more clear it is with it. Glad you think so too ๐Ÿ˜