What's the fastest/best way to compare two arrays and return the difference? Much like array_diff
in PHP. Is there an easy function or am I going to have to create one via each()
? or a foreach
loop?

- 10,007
- 11
- 42
- 64

- 10,422
- 29
- 111
- 186
-
Hiya man, I reckon you can use `inArray` and populate the difference between 2 Arrays; I have pasted a working demo for you, hope it helps B-) – Tats_innit Jun 07 '12 at 08:15
-
duplicate of http://stackoverflow.com/questions/1187518/javascript-array-difference (even if it was already linked elsewhere in there, somewhere) – cregox May 14 '15 at 18:45
-
You probably want [this answer from a past SO question](http://stackoverflow.com/a/4026828/304588). It builds on the Array prototype. – Richard Neil Ilagan Jun 07 '12 at 07:48
10 Answers
I know this is an old question, but I thought I would share this little trick.
var diff = $(old_array).not(new_array).get();
diff
now contains what was in old_array
that is not in new_array

- 7,954
- 6
- 30
- 63
-
2short and sweet.. just like i like it.. i used that with `$.merge()` to concatenate differences in specific a specific order... – kingkode Oct 09 '13 at 17:17
-
1will this work if the array contains objects? I'm trying to compare objects within two arrays – Batman Jan 19 '14 at 06:53
-
2Here is a scenario. This works fine for `$(['h','h','h','h','h']).not($(["a", "a", "a"]))` but for an array like `$(['h','h','h','h','h']).not($(["a", "a", "a", "h"]))` (NOTICE the last "h" in the array) it returns an empty array. The difference is not returned. Hence, it is faulty. – Vishnu Narang Feb 06 '14 at 07:18
-
2@VishnuNarang I think you are misunderstanding a few things here. Firstly how array differencing works, and secondly not reading the actual question the OP asked. Lets deal with the first misunderstanding. Returning an empty array in your second example is EXACTLY the right result. It is returning what was in the first array, that is not in the second (i.e nothing). This is the "difference" between the first array and the second. Secondly, the OP asked for a jQuery Function like PHP's (array_diff). This is it! Your example run through PHP's array_diff() function produces an empty array as well – superphonic Feb 06 '14 at 10:50
-
@VishnuNarang I am pretty confident that PHP's array_diff() function is not faulty. – superphonic Feb 06 '14 at 10:51
-
Firstly i did not answer the asked question. I merely commented on this answer indicating what Jquery does. And using `.not` to get the different is probably not the best way to do it because it does not give the difference in the real sense. It just does what you rightly explained. So the point is, `.not` is not the same as difference between the two arrays. My example clearly says that the arrays are different but the return value is empty. Hence, i rest my case with that. Anyways, thanks. – Vishnu Narang Feb 06 '14 at 12:02
-
Oh FYI, the code i'm working on had the `.not` implementation and in the process of solving a production bug, i discovered it was used for a scenario which cannot be solved using `.not`. Hence, if you want the difference between two arrays, i would rather suggest to use something more robust. Ofcourse that depends of the needs too. Thanks again. – Vishnu Narang Feb 06 '14 at 12:06
-
@VishnuNarang Unfortunately I do not really understand what it is your are trying to do, or what you mean by `does not give the difference in the real sense`?. I think you may be talking about a "Symmetric Difference" which this solution isn't and the OP didn't ask for. It is however the correct answer to this question, and is definitely NOT faulty, as you said in your original comment. – superphonic Feb 06 '14 at 14:42
-
@superphonic is there a doc that talks about using jQuery with non-elements? Like here you used it with an array, but I don't see any docs about it. – Jayen Jul 27 '14 at 05:43
-
@Jayen Not that I know of... When you use a regular array with `.not()`, jQuery actually uses it's built-in utility `.grep()` which is specifically for manipulating arrays. jQuery has lots of utilities that do not deal with elements, you can see the full list here http://api.jquery.com/category/utilities/ – superphonic Jul 28 '14 at 11:48
-
jQuery `not` no longer works with generic objects as of 3.0.0-rc1. See https://github.com/jquery/jquery/issues/3147 – Marc-André Lafortune Jun 09 '16 at 15:39
-
Working demo http://jsfiddle.net/u9xES/
Good link (Jquery Documentation): http://docs.jquery.com/Main_Page {you can search or read APIs here}
Hope this will help you if you are looking to do it in JQuery.
The alert in the end prompts the array of uncommon element Array i.e. difference between 2 array.
Please lemme know if I missed anything, cheers!
Code
var array1 = [1, 2, 3, 4, 5, 6];
var array2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var difference = [];
jQuery.grep(array2, function(el) {
if (jQuery.inArray(el, array1) == -1) difference.push(el);
});
alert(" the difference is " + difference); // Changed variable name

- 22,508
- 11
- 59
- 94

- 33,991
- 10
- 71
- 77
-
8This method is cool, but should consider the case if array2's length is less than array1 – Jimmy Huang Oct 30 '12 at 11:31
-
15More elegant : simply `difference = $.grep(a1,function(x) {return $.inArray(x, a2) < 0})` – Jocelyn delalande Feb 15 '13 at 15:02
-
2Great answer. However would like to point out that you're using `.grep` like `.each`; should be `difference = $.grep(array2, function(el) { return $.inArray( el, array1 ) == -1; })` – PeterKA Aug 27 '14 at 18:59
-
@user3558931 Sure `:)` thanks! I reckon extra stuff was there to push it in a new array. – Tats_innit Aug 28 '14 at 10:38
-
1Dude, you are love :) I was stuck for about 2 days and you lead me to the other end. – Hassan Murtaza Jan 22 '16 at 13:41
-
-
1Fiddle for @Jocelyndelalande's comment: http://jsfiddle.net/cqsLvxod/ – Shivam Sharma Mar 06 '20 at 10:15
-
The result won't report it if array1 has value A while array2 not. – liudaxingtx May 26 '20 at 19:19
use underscore as :
_.difference(array1,array2)

- 922
- 10
- 19
-
1This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post. – AlSki Feb 27 '14 at 14:22
-
2@AlSki it gives the answer to the question asked! compares the two arrays and returns the diff. – anurag_29 Feb 28 '14 at 13:31
-
1@anurag_29 The question was how to do it with jQuery, not underscore. – reergymerej Mar 31 '15 at 20:46
-
1@AlSki When the answer is being posted YEARS later, t's appropriate, I think, to post an answer that involves the use of a different library than the question asked about, because that is a possible answer to the question - not knowing one way or the other if the OP, or others visiting the question years later, are aware of the library. – Dan Nissenbaum Jun 25 '15 at 04:55
var arrayDiff = function (firstArr, secondArr) {
var i, o = [], fLen = firstArr.length, sLen = secondArr.length, len;
if (fLen > sLen) {
len = sLen;
} else if (fLen < sLen) {
len = fLen;
} else {
len = sLen;
}
for (i=0; i < len; i++) {
if (firstArr[i] !== secondArr[i]) {
o.push({idx: i, elem1: firstArr[i], elem2: secondArr[i]}); //idx: array index
}
}
if (fLen > sLen) { // first > second
for (i=sLen; i< fLen; i++) {
o.push({idx: i, 0: firstArr[i], 1: undefined});
}
} else if (fLen < sLen) {
for (i=fLen; i< sLen; i++) {
o.push({idx: i, 0: undefined, 1: secondArr[i]});
}
}
return o;
};
/** SUBTRACT ARRAYS **/
function subtractarrays(array1, array2){
var difference = [];
for( var i = 0; i < array1.length; i++ ) {
if( $.inArray( array1[i], array2 ) == -1 ) {
difference.push(array1[i]);
}
}
return difference;
}
You can then call the function anywhere in your code.
var I_like = ["love", "sex", "food"];
var she_likes = ["love", "food"];
alert( "what I like and she does't like is: " + subtractarrays( I_like, she_likes ) ); //returns "Naughty"!
This works in all cases and avoids the problems in the methods above. Hope that helps!

- 10,422
- 29
- 111
- 186

- 5,068
- 44
- 38
The short version can be like this:
const diff = (a, b) => b.filter((i) => a.indexOf(i) === -1);
result:
diff(['a', 'b'], ['a', 'b', 'c', 'd']);
["c", "d"]

- 1,693
- 16
- 18
if you also want to compare the order of the answer you can extend the answer to something like this:
Array.prototype.compareTo = function (array2){
var array1 = this;
var difference = [];
$.grep(array2, function(el) {
if ($.inArray(el, array1) == -1) difference.push(el);
});
if( difference.length === 0 ){
var $i = 0;
while($i < array1.length){
if(array1[$i] !== array2[$i]){
return false;
}
$i++;
}
return true;
}
return false;
}

- 400
- 5
- 22
In this way you don't need to worry about if the first array is smaller than the second one.
var arr1 = [1, 2, 3, 4, 5, 6,10],
arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9];
function array_diff(array1, array2){
var difference = $.grep(array1, function(el) { return $.inArray(el,array2) < 0});
return difference.concat($.grep(array2, function(el) { return $.inArray(el,array1) < 0}));;
}
console.log(array_diff(arr1, arr2));

- 712
- 5
- 20
Array operations like this is not jQuery's strongest point. You should consider a library such as Underscorejs, specifically the difference function.

- 10,358
- 1
- 26
- 46
This should work with unsorted arrays, double values and different orders and length, while giving you the filtered values form array1, array2, or both.
function arrayDiff(arr1, arr2) {
var diff = {};
diff.arr1 = arr1.filter(function(value) {
if (arr2.indexOf(value) === -1) {
return value;
}
});
diff.arr2 = arr2.filter(function(value) {
if (arr1.indexOf(value) === -1) {
return value;
}
});
diff.concat = diff.arr1.concat(diff.arr2);
return diff;
};
var firstArray = [1,2,3,4];
var secondArray = [4,6,1,4];
console.log( arrayDiff(firstArray, secondArray) );
console.log( arrayDiff(firstArray, secondArray).arr1 );
// => [ 2, 3 ]
console.log( arrayDiff(firstArray, secondArray).concat );
// => [ 2, 3, 6 ]

- 289
- 4
- 14