DEV Community

Merging Arrays in Javascript

Ben Greenberg on October 09, 2017

In my next installment of coding concepts for liberal arts programmers (i.e. coders who do not come from a math or science background) we will look...
Collapse
 
elarcis profile image
Elarcis • Edited

You can also make use of ES6 to merge any number of lists in a single call:

function mergeArrays(base, ...arrays) { 
  return base
    .concat(...arrays)
    .sort((a, b) => a - b);
}

Please mind that when using Array.prototype.sort without argument, the sorting is done via Unicode endpoints – pretty much an alphabetical sort, which means that this array:

[1, 8, 11, 10]

will be sorted into this one:

[1, 10, 11, 8]
Collapse
 
ethan profile image
Ethan Stewart

This is a great way to think through and implement the algorithm for solving this problem. This is my take on a simpler, more compact solution using the ES6 spread operator and the built-in sort method on JS arrays:

function mergeLists(firstList, secondList) {
  return [...firstList, ...secondList].sort();
}

If you can't use ES6 for whatever reason, the concat method would allow you to still keep this nice and simple:

function mergeLists(firstList, secondList) {
  return firstList.concat(secondList).sort();
}
Collapse
 
bengreenberg profile image
Ben Greenberg

Those are very compact, love the simplicity of it! My goal in these posts is to breakdown what's happening behind the scenes a bit so I intentionally spell out the steps rather than using a built in method. The idea being that once someone has some idea what's happening "behind the scenes" then they will more fully appreciate a language's built in methods.

Collapse
 
janjuks profile image
janjuks • Edited

sort() should be sort((a, b) => a - b)
Otherwise, surprise, surprise - [1, 2, 11].sort() -> [1, 11, 2]

Collapse
 
ethan profile image
Ethan Stewart

I forgot about that, good catch!

Collapse
 
xavierartot profile image
Xavier Artot • Edited

Another solution, simple and faster.
sort an array
developer.mozilla.org/en-US/docs/W...
concat 2 arrays:
developer.mozilla.org/en-US/docs/W...

Collapse
 
jvanbruegge profile image
Jan van Brügge • Edited

Simpler yes, faster no. If you look at algorithmic complexity, the sort() function has at least O(n*log(n)). Presorted merge sort (what this basicly is) has a complexity of O(n).

A canonical implementation would be:

function presortedMergesort(a, b) {
  let p1 = 0, p2 = 0;
  let result = Array(a.length + b.length)

  for(let i = 0; i < result.length; i++) {
    if(b[p2] === undefined || 
      (a[p1] !== undefined && a[p1] <= b[p2])
    ) {
      result[i] = a[p1];
      p1++;
    } else {
      result[i] = b[p2];
      p2++;
    }
  }
  return result;
}

As you can see, only one loop, with n = |a| + |b| executions
}

Collapse
 
lgreensh profile image
Liam Dalzell-Greenshaw

I think that as this is a series for relative beginners, it's important to emphasise the fact that often, simpler code is better than "faster" code. If you're working with arrays as small as in the example, the difference will be essentially negligible.

I usually take the rule that if there is any noticeable slowness in my code, then I go and try and optimise things like this, but in the vast majority of situations (I would suggest), this sort of complexity is overkill.

Thread Thread
 
jvanbruegge profile image
Jan van Brügge • Edited

Yes of course, always write simple first, then measure performance and optimize where needed.
My point was that using properties like presorted arrays can allow you to go beyond the theoretical limit of O(n*log(n)) that a normal sorting algorithmus has.

Thread Thread
 
lgreensh profile image
Liam Dalzell-Greenshaw

Absolutely, definitely useful stuff to know!

Collapse
 
bengreenberg profile image
Ben Greenberg

Thanks for sharing!

Collapse
 
crongm profile image
Carlos Garcia ★

Thanks for the article. This is a good lesson on algorithm thinking and building. However, the wording in the next phrase confused me a bit:

...we return the first list without that number and, if the opposite is true, we return the second list without its smallest number...

What it is returning is the smallest number found from the two lists/arrays (the iteratedNum variable would then hold this number), and at the same time modifying the original array to not have that number anymore.

Collapse
 
janjuks profile image
janjuks

Tiny little thing - you are hiding iteratedNum by defining it inside and outside while loop.

Collapse
 
bengreenberg profile image
Ben Greenberg

Yes, you are right, thanks for noticing!

Collapse
 
millard_ profile image
Millard

Just for fun

let firstList = [4, 6, 8, 9]
let secondList = [2, 3, 5, 7]

`${firstList},${secondList}`.split(",")
Collapse
 
dimpiax profile image
Dmytro Pylypenko

Really faster will be approach to concat and sort.

Collapse
 
rattanakchea profile image
Rattanak Chea

This works and is quite easy to understand. I just want to add, i prefer a pure function where it does always return what's expected without modifying the inputs.