# How to get the difference between two arrays in Javascript?

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"]
``````

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]);
``````

## Plain JavaScript

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'];
``````
1. 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;
}
``````
2. 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;
}
``````

## Lodash / Underscore

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.

## ES6 Set, for very large arrays

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));
}
``````

## Notes

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)

## ES7 (ECMAScript 2016)

``````// 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));
}));
}
``````

## ES6 (ECMAScript 2015)

``````// 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);
}));
}
``````

## ES5 (ECMAScript 5.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"]
``````

## Difference between Arrays of Objects

``````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}]
``````

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;
});
``````

A cleaner approach in ES6 is the following solution.

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

## Difference

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

## Intersection

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

## Disjunctive Union (Symmetric Difference)

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

## Functional approach with ES2015

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.

### Left `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) );``````

### Right `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!

### Symmetric `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']
``````

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" ]`.

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 ]`

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]
``````

``````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]
``````

``````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);
``````

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)

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;
});
}

diffArray(a1, a2);``````

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

• 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;
}

"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;
}``````

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

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 = [];

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++;
}
}

if( np < n.length )
a = a.concat(n.slice(np, n.length));
if( op < o.length )
r = r.concat(o.slice(op, o.length));

}
``````

I was looking for a simple answer that didn't involve using different libraries, and I came up with my own that I don't think has been mentioned here. I don't know how efficient it is or anything but it works;

``````    function find_diff(arr1, arr2) {
diff = [];
joined = arr1.concat(arr2);
for( i = 0; i <= joined.length; i++ ) {
current = joined[i];
if( joined.indexOf(current) == joined.lastIndexOf(current) ) {
diff.push(current);
}
}
return diff;
}
``````

For my code I need duplicates taken out as well, but I guess that isn't always preferred.

I guess the main downside is it's potentially comparing many options that have already been rejected.

littlebit fix for the best answer

``````function arr_diff(a1, a2)
{
var a=[], diff=[];
for(var i=0;i<a1.length;i++)
a[a1[i]]=a1[i];
for(var i=0;i<a2.length;i++)
if(a[a2[i]]) delete a[a2[i]];
else a[a2[i]]=a2[i];
for(var k in a)
diff.push(a[k]);
return diff;
}
``````

this will take current type of element in consideration. b/c when we make a[a1[i]] it converts a value to string from its oroginal value, so we lost actual value.

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]
``````

//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
}
``````

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])
``````