Is there a way to return the difference between two arrays in JavaScript?

For example:

var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; // need ["c", "d"]

Skip to content
# How to get the difference between two arrays in JavaScript?

## The Question :

*864 people think this question is useful*
*The Question Comments :*
## The Answer 1

*247 people think this answer is useful*
## The Answer 2

*1680 people think this answer is useful*

## The Answer 3

*921 people think this answer is useful*
## The Answer 4

*307 people think this answer is useful*
## The Answer 5

*165 people think this answer is useful*
## The Answer 6

*84 people think this answer is useful*
## Plain JavaScript

## Lodash / Underscore

## ES6 Set, for very large arrays

## Notes

## The Answer 7

*58 people think this answer is useful*

## ES7 (ECMAScript 2016)

## ES6 (ECMAScript 2015)

## ES5 (ECMAScript 5.1)

*Difference between Arrays of Objects*

## The Answer 8

*57 people think this answer is useful*
**Difference**

**Intersection**

## Disjunctive Union (Symmetric Difference)

## The Answer 9

*44 people think this answer is useful*
## The Answer 10

*33 people think this answer is useful*
## The Answer 11

*18 people think this answer is useful*
## The Answer 12

*18 people think this answer is useful*
## The Answer 13

*15 people think this answer is useful*
## Functional approach with ES2015

### Left

### Right

### Symmetric

## The Answer 14

*12 people think this answer is useful*
## The Answer 15

*12 people think this answer is useful*
## The Answer 16

*10 people think this answer is useful*
## The Answer 17

*7 people think this answer is useful*
## The Answer 18

*7 people think this answer is useful*
## The Answer 19

*6 people think this answer is useful*
## The Answer 20

*4 people think this answer is useful*
## The Answer 21

*4 people think this answer is useful*
## The Answer 22

*3 people think this answer is useful*
## The Answer 23

*3 people think this answer is useful*
## The Answer 24

*3 people think this answer is useful*
## The Answer 25

*3 people think this answer is useful*
## The Answer 26

*3 people think this answer is useful*
## The Answer 27

*3 people think this answer is useful*
## The Answer 28

*3 people think this answer is useful*
## The Answer 29

*2 people think this answer is useful*
## The Answer 30

*2 people think this answer is useful*

2021-01-10

Is there a way to return the difference between two arrays in JavaScript?

For example:

var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; // need ["c", "d"]

- Symmetric or non-symmetric?
- With new ES6 function this can be done as a simple one liner (it will take a lot of time to be able to use in all major browsers). In any case check my answer
- an important aspect of the solution is performance. the asymptotic time complexity of this type of operation – in other languages – is
`O(a1.length x log(a2.length))`

– is this performance possible in JavaScript? - Check my library, it can help you with this, @netilon/differify is one of the fastest diff libraries for object/array comparison: npmjs.com/package/@netilon/differify

I assume you are comparing a normal array. If not, you need to change the *for* loop to a *for .. in* loop.

function arr_diff (a1, a2) { var a = [], diff = []; for (var i = 0; i < a1.length; i++) { a[a1[i]] = true; } for (var i = 0; i < a2.length; i++) { if (a[a2[i]]) { delete a[a2[i]]; } else { a[a2[i]] = true; } } for (var k in a) { diff.push(k); } return diff; } console.log(arr_diff(['a', 'b'], ['a', 'b', 'c', 'd'])); console.log(arr_diff("abcd", "abcde")); console.log(arr_diff("zxc", "zxc"));

A better solution, if you don’t care about backward compatibility, is using filter. But still, this solution works.

There is a better way using ES7:

**Intersection**

let intersection = arr1.filter(x => arr2.includes(x));

For `[1,2,3] [2,3]`

it will yield `[2,3]`

. On the other hand, for `[1,2,3] [2,3,5]`

will return the same thing.

**Difference**

let difference = arr1.filter(x => !arr2.includes(x));

For `[1,2,3] [2,3]`

it will yield `[1]`

. On the other hand, for `[1,2,3] [2,3,5]`

will return the same thing.

For a **symmetric difference**, you can do:

let difference = arr1 .filter(x => !arr2.includes(x)) .concat(arr2.filter(x => !arr1.includes(x)));

This way, you will get an array containing all the elements of arr1 that are not in arr2 and vice-versa

As @Joshaven Potter pointed out on his answer, you can add this to Array.prototype so it can be used like this:

Array.prototype.diff = function(arr2) { return this.filter(x => !arr2.includes(x)); } [1, 2, 3].diff([2, 3])

Array.prototype.diff = function(a) { return this.filter(function(i) {return a.indexOf(i) < 0;}); }; //////////////////// // Examples //////////////////// [1,2,3,4,5,6].diff( [3,4,5] ); // => [1, 2, 6] ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]); // => ["test5", "test6"]

Array.prototype.diff = function(a) { return this.filter(function(i) {return a.indexOf(i) < 0;}); }; //////////////////// // Examples //////////////////// var dif1 = [1,2,3,4,5,6].diff( [3,4,5] ); console.log(dif1); // => [1, 2, 6] var dif2 = ["test1", "test2","test3","test4","test5","test6"].diff(["test1","test2","test3","test4"]); console.log(dif2); // => ["test5", "test6"]

**Note** indexOf and filter are not available in ie before ie9.

This is by far the easiest way to get exactly the result you are looking for, using jQuery:

var diff = $(old_array).not(new_array).get();

`diff`

now contains what was in `old_array`

that is not in `new_array`

The difference method in Underscore (or its drop-in replacement, Lo-Dash) can do this too:

(R)eturns the values from array that are not present in the other arrays _.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4]

As with any Underscore function, you could also use it in a more object-oriented style:

_([1, 2, 3, 4, 5]).difference([5, 2, 10]);

There are two possible intepretations for “difference”. I’ll let you choose which one you want. Say you have:

var a1 = ['a', 'b' ]; var a2 = [ 'b', 'c'];

If you want to get

`['a']`

, use this function:function difference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } return result; }

If you want to get

`['a', 'c']`

(all elements contained in*either*`a1`

or`a2`

, but not both — the so-called*symmetric difference*), use this function:function symmetricDifference(a1, a2) { var result = []; for (var i = 0; i < a1.length; i++) { if (a2.indexOf(a1[i]) === -1) { result.push(a1[i]); } } for (i = 0; i < a2.length; i++) { if (a1.indexOf(a2[i]) === -1) { result.push(a2[i]); } } return result; }

If you are using lodash, you can use `_.difference(a1, a2)`

(case 1 above) or `_.xor(a1, a2)`

(case 2).

If you are using Underscore.js, you can use the `_.difference(a1, a2)`

function for case 1.

The code above works on all browsers. However, for large arrays of more than about 10,000 items, it becomes quite slow, because it has O(n²) complexity. On many modern browsers, we can take advantage of the ES6 `Set`

object to speed things up. Lodash automatically uses `Set`

when it’s available. If you are not using lodash, use the following implementation, inspired by Axel Rauschmayer’s blog post:

function difference(a1, a2) { var a2Set = new Set(a2); return a1.filter(function(x) { return !a2Set.has(x); }); } function symmetricDifference(a1, a2) { return difference(a1, a2).concat(difference(a2, a1)); }

The behavior for all examples may be surprising or non-obvious if you care about -0, +0, NaN or sparse arrays. (For most uses, this doesn’t matter.)

To get the **symmetric difference** you need to compare the arrays in both ways (or in all the ways in case of multiple arrays)

// diff between just two arrays: function arrayDiff(a, b) { return [ ...a.filter(x => !b.includes(x)), ...b.filter(x => !a.includes(x)) ]; } // diff between multiple arrays: function arrayDiff(...arrays) { return [].concat(...arrays.map( (arr, i) => { const others = arrays.slice(0); others.splice(i, 1); const unique = [...new Set([].concat(...others))]; return arr.filter(x => !unique.includes(x)); })); }

// diff between just two arrays: function arrayDiff(a, b) { return [ ...a.filter(x => b.indexOf(x) === -1), ...b.filter(x => a.indexOf(x) === -1) ]; } // diff between multiple arrays: function arrayDiff(...arrays) { return [].concat(...arrays.map( (arr, i) => { const others = arrays.slice(0); others.splice(i, 1); const unique = [...new Set([].concat(...others))]; return arr.filter(x => unique.indexOf(x) === -1); })); }

// diff between just two arrays: function arrayDiff(a, b) { var arrays = Array.prototype.slice.call(arguments); var diff = []; arrays.forEach(function(arr, i) { var other = i === 1 ? a : b; arr.forEach(function(x) { if (other.indexOf(x) === -1) { diff.push(x); } }); }) return diff; } // diff between multiple arrays: function arrayDiff() { var arrays = Array.prototype.slice.call(arguments); var diff = []; arrays.forEach(function(arr, i) { var others = arrays.slice(0); others.splice(i, 1); var otherValues = Array.prototype.concat.apply([], others); var unique = otherValues.filter(function (x, j) { return otherValues.indexOf(x) === j; }); diff = diff.concat(arr.filter(x => unique.indexOf(x) === -1)); }); return diff; }

**Example:**

// diff between two arrays: const a = ['a', 'd', 'e']; const b = ['a', 'b', 'c', 'd']; arrayDiff(a, b); // (3) ["e", "b", "c"] // diff between multiple arrays const a = ['b', 'c', 'd', 'e', 'g']; const b = ['a', 'b']; const c = ['a', 'e', 'f']; arrayDiff(a, b, c); // (4) ["c", "d", "g", "f"]

function arrayDiffByKey(key, ...arrays) { return [].concat(...arrays.map( (arr, i) => { const others = arrays.slice(0); others.splice(i, 1); const unique = [...new Set([].concat(...others))]; return arr.filter( x => !unique.some(y => x[key] === y[key]) ); })); }

**Example:**

const a = [{k:1}, {k:2}, {k:3}]; const b = [{k:1}, {k:4}, {k:5}, {k:6}]; const c = [{k:3}, {k:5}, {k:7}]; arrayDiffByKey('k', a, b, c); // (4) [{k:2}, {k:4}, {k:6}, {k:7}]

A cleaner approach in ES6 is the following solution.

var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd'];

a2.filter(d => !a1.includes(d)) // gives ["c", "d"]

a2.filter(d => a1.includes(d)) // gives ["a", "b"]

[ ...a2.filter(d => !a1.includes(d)), ...a1.filter(d => !a2.includes(d)) ]

You could use a Set in this case. It is optimized for this kind of operation (union, intersection, difference).

Make sure it applies to your case, once it allows no duplicates.

var a = new JS.Set([1,2,3,4,5,6,7,8,9]); var b = new JS.Set([2,4,6,8]); a.difference(b) // -> Set{1,3,5,7,9}

function diff(a1, a2) { return a1.concat(a2).filter(function(val, index, arr){ return arr.indexOf(val) === arr.lastIndexOf(val); }); }

Merge both the arrays, unique values will appear only once so indexOf() will be the same as lastIndexOf().

to subtract one array from another, simply use the snippet below:

var a1 = ['1','2','3','4','6']; var a2 = ['3','4','5']; var items = new Array(); items = jQuery.grep(a1,function (item) { return jQuery.inArray(item, a2) < 0; });

It will returns [‘1,’2′,’6’] that are items of first array which don’t exist in the second.

Therefore, according to your problem sample, following code is the exact solution:

var array1 = ["test1", "test2","test3", "test4"]; var array2 = ["test1", "test2","test3","test4", "test5", "test6"]; var _array = new Array(); _array = jQuery.grep(array2, function (item) { return jQuery.inArray(item, array1) < 0; });

With the arrival of ES6 with sets and splat operator (at the time of being works only in Firefox, check compatibility table), you can write the following one liner:

var a = ['a', 'b', 'c', 'd']; var b = ['a', 'b']; var b1 = new Set(b); var difference = [...new Set(a.filter(x => !b1.has(x)))];

which will result in `[ "c", "d" ]`

.

Computing the `difference`

between two arrays is one of the `Set`

operations. The term already indicates that the native `Set`

type should be used, in order to increase the lookup speed. Anyway, there are three permutations when you compute the difference between two sets:

[+left difference] [-intersection] [-right difference] [-left difference] [-intersection] [+right difference] [+left difference] [-intersection] [+right difference]

Here is a functional solution that reflects these permutations.

`difference`

:// small, reusable auxiliary functions const apply = f => x => f(x); const flip = f => y => x => f(x) (y); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // left difference const differencel = xs => ys => { const zs = createSet(ys); return filter(x => zs.has(x) ? false : true ) (xs); }; // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,3,6,7,8,9]; // run the computation console.log( differencel(xs) (ys) );

`difference`

:`differencer`

is trivial. It is just `differencel`

with flipped arguments. You can write a function for convenience: `const differencer = flip(differencel)`

. That’s all!

`difference`

:Now that we have the left and right one, implementing the symmetric `difference`

gets trivial as well:

// small, reusable auxiliary functions const apply = f => x => f(x); const flip = f => y => x => f(x) (y); const concat = y => xs => xs.concat(y); const createSet = xs => new Set(xs); const filter = f => xs => xs.filter(apply(f)); // left difference const differencel = xs => ys => { const zs = createSet(ys); return filter(x => zs.has(x) ? false : true ) (xs); }; // symmetric difference const difference = ys => xs => concat(differencel(xs) (ys)) (flip(differencel) (xs) (ys)); // mock data const xs = [1,2,2,3,4,5]; const ys = [0,1,2,3,3,3,6,7,8,9]; // run the computation console.log( difference(xs) (ys) );

I guess this example is a good starting point to obtain an impression what functional programming means:

**Programming with building blocks that can be plugged together in many different ways.**

A solution using `indexOf()`

will be ok for small arrays but as they grow in length the performance of the algorithm approaches `O(n^2)`

. Here’s a solution that will perform better for very large arrays by using objects as associative arrays to store the array entries as keys; it also eliminates duplicate entries automatically but only works with string values (or values which can be safely stored as strings):

function arrayDiff(a1, a2) { var o1={}, o2={}, diff=[], i, len, k; for (i=0, len=a1.length; i<len; i++) { o1[a1[i]] = true; } for (i=0, len=a2.length; i<len; i++) { o2[a2[i]] = true; } for (k in o1) { if (!(k in o2)) { diff.push(k); } } for (k in o2) { if (!(k in o1)) { diff.push(k); } } return diff; } var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; arrayDiff(a1, a2); // => ['c', 'd'] arrayDiff(a2, a1); // => ['c', 'd']

Another way to solve the problem

function diffArray(arr1, arr2) { return arr1.concat(arr2).filter(function (val) { if (!(arr1.includes(val) && arr2.includes(val))) return val; }); } diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]

Also, you can use arrow function syntax:

const diffArray = (arr1, arr2) => arr1.concat(arr2) .filter(val => !(arr1.includes(val) && arr2.includes(val))); diffArray([1, 2, 3, 7], [3, 2, 1, 4, 5]); // return [7, 4, 5]

The above answer by Joshaven Potter is great. But it returns elements in array B that are not in array C, but not the other way around. For example, if `var a=[1,2,3,4,5,6].diff( [3,4,5,7]);`

then it will output: ==> `[1,2,6]`

, but **not** `[1,2,6,7]`

, which is the actual difference between the two. You can still use Potter’s code above but simply redo the comparison once backwards too:

Array.prototype.diff = function(a) { return this.filter(function(i) {return !(a.indexOf(i) > -1);}); }; //////////////////// // Examples //////////////////// var a=[1,2,3,4,5,6].diff( [3,4,5,7]); var b=[3,4,5,7].diff([1,2,3,4,5,6]); var c=a.concat(b); console.log(c);

This should output: `[ 1, 2, 6, 7 ]`

Array.prototype.difference = function(e) { return this.filter(function(i) {return e.indexOf(i) < 0;}); }; eg:- [1,2,3,4,5,6,7].difference( [3,4,5] ); => [1, 2, 6 , 7]

Very Simple Solution with the filter function of JavaScript:

var a1 = ['a', 'b']; var a2 = ['a', 'b', 'c', 'd']; function diffArray(arr1, arr2) { var newArr = []; var myArr = arr1.concat(arr2); newArr = myArr.filter(function(item){ return arr2.indexOf(item) < 0 || arr1.indexOf(item) < 0; }); alert(newArr); } diffArray(a1, a2);

How about this:

Array.prototype.contains = function(needle){ for (var i=0; i<this.length; i++) if (this[i] == needle) return true; return false; } Array.prototype.diff = function(compare) { return this.filter(function(elem) {return !compare.contains(elem);}) } var a = new Array(1,4,7, 9); var b = new Array(4, 8, 7); alert(a.diff(b));

So this way you can do `array1.diff(array2)`

to get their difference (Horrible time complexity for the algorithm though – O(array1.length x array2.length) I believe)

Using http://phrogz.net/JS/ArraySetMath.js you can:

var array1 = ["test1", "test2","test3", "test4"]; var array2 = ["test1", "test2","test3","test4", "test5", "test6"]; var array3 = array2.subtract( array1 ); // ["test5", "test6"] var array4 = array1.exclusion( array2 ); // ["test5", "test6"]

function diffArray(arr1, arr2) { var newArr = arr1.concat(arr2); return newArr.filter(function(i){ return newArr.indexOf(i) == newArr.lastIndexOf(i); }); }

this is works for me

You can use underscore.js : http://underscorejs.org/#intersection

You have needed methods for array :

_.difference([1, 2, 3, 4, 5], [5, 2, 10]); => [1, 3, 4] _.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]); => [1, 2]

- Pure JavaScript solution (no libraries)
- Compatible with older browsers (doesn’t use
`filter`

) - O(n^2)
- Optional
`fn`

callback parameter that lets you specify how to compare array items

function diff(a, b, fn){ var max = Math.max(a.length, b.length); d = []; fn = typeof fn === 'function' ? fn : false for(var i=0; i < max; i++){ var ac = i < a.length ? a[i] : undefined bc = i < b.length ? b[i] : undefined; for(var k=0; k < max; k++){ ac = ac === undefined || (k < b.length && (fn ? fn(ac, b[k]) : ac == b[k])) ? undefined : ac; bc = bc === undefined || (k < a.length && (fn ? fn(bc, a[k]) : bc == a[k])) ? undefined : bc; if(ac == undefined && bc == undefined) break; } ac !== undefined && d.push(ac); bc !== undefined && d.push(bc); } return d; } alert( "Test 1: " + diff( [1, 2, 3, 4], [1, 4, 5, 6, 7] ).join(', ') + "\nTest 2: " + diff( [{id:'a',toString:function(){return this.id}},{id:'b',toString:function(){return this.id}},{id:'c',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}], [{id:'a',toString:function(){return this.id}},{id:'e',toString:function(){return this.id}},{id:'f',toString:function(){return this.id}},{id:'d',toString:function(){return this.id}}], function(a, b){ return a.id == b.id; } ).join(', ') );

This is working: basically merge the two arrays, look for the duplicates and push what is not duplicated into a new array which is the difference.

function diff(arr1, arr2) { var newArr = []; var arr = arr1.concat(arr2); for (var i in arr){ var f = arr[i]; var t = 0; for (j=0; j<arr.length; j++){ if(arr[j] === f){ t++; } } if (t === 1){ newArr.push(f); } } return newArr; }

//es6 approach

function diff(a, b) { var u = a.slice(); //dup the array b.map(e => { if (u.indexOf(e) > -1) delete u[u.indexOf(e)] else u.push(e) //add non existing item to temp array }) return u.filter((x) => {return (x != null)}) //flatten result }

**Symmetric** and **linear complexity**. Requires ES6.

function arrDiff(arr1, arr2) { var arrays = [arr1, arr2].sort((a, b) => a.length - b.length); var smallSet = new Set(arrays[0]); return arrays[1].filter(x => !smallSet.has(x)); }

yet another answer, but seems nobody mentioned jsperf where they compare several algorithms and technology support: https://jsperf.com/array-difference-javascript seems using filter gets the best results. thanks

Use extra memory to do this. That way you can solve it with less time complexity, O(n) instead of o(n*n).

function getDiff(arr1,arr2){ let k = {}; let diff = [] arr1.map(i=>{ if (!k.hasOwnProperty(i)) { k[i] = 1 } } ) arr2.map(j=>{ if (!k.hasOwnProperty(j)) { k[j] = 1; } else { k[j] = 2; } } ) for (var i in k) { if (k[i] === 1) diff.push(+i) } return diff } getDiff([4, 3, 52, 3, 5, 67, 9, 3],[4, 5, 6, 75, 3, 334, 5, 5, 6])

Just thinking… for the sake of a challenge 😉 would this work… (for basic arrays of strings, numbers, etc.) no nested arrays

function diffArrays(arr1, arr2, returnUnion){ var ret = []; var test = {}; var bigArray, smallArray, key; if(arr1.length >= arr2.length){ bigArray = arr1; smallArray = arr2; } else { bigArray = arr2; smallArray = arr1; } for(var i=0;i<bigArray.length;i++){ key = bigArray[i]; test[key] = true; } if(!returnUnion){ //diffing for(var i=0;i<smallArray.length;i++){ key = smallArray[i]; if(!test[key]){ test[key] = null; } } } else { //union for(var i=0;i<smallArray.length;i++){ key = smallArray[i]; if(!test[key]){ test[key] = true; } } } for(var i in test){ ret.push(i); } return ret; } array1 = "test1", "test2","test3", "test4", "test7" array2 = "test1", "test2","test3","test4", "test5", "test6" diffArray = diffArrays(array1, array2); //returns ["test5","test6","test7"] diffArray = diffArrays(array1, array2, true); //returns ["test1", "test2","test3","test4", "test5", "test6","test7"]

Note the sorting will likely not be as noted above… but if desired, call .sort() on the array to sort it.

I wanted a similar function which took in an old array and a new array and gave me an array of added items and an array of removed items, and I wanted it to be efficient (so no .contains!).

You can play with my proposed solution here: http://jsbin.com/osewu3/12.

Can anyone see any problems/improvements to that algorithm? Thanks!

Code listing:

function diff(o, n) { // deal with empty lists if (o == undefined) o = []; if (n == undefined) n = []; // sort both arrays (or this won't work) o.sort(); n.sort(); // don't compare if either list is empty if (o.length == 0 || n.length == 0) return {added: n, removed: o}; // declare temporary variables var op = 0; var np = 0; var a = []; var r = []; // compare arrays and add to add or remove lists while (op < o.length && np < n.length) { if (o[op] < n[np]) { // push to diff? r.push(o[op]); op++; } else if (o[op] > n[np]) { // push to diff? a.push(n[np]); np++; } else { op++;np++; } } // add remaining items if( np < n.length ) a = a.concat(n.slice(np, n.length)); if( op < o.length ) r = r.concat(o.slice(op, o.length)); return {added: a, removed: r}; }