Difference Between Two Arrays

How to get the difference between two arrays in JavaScript?

This answer was written in 2009, so it is a bit outdated, also it's rather educational for understanding the problem. Best solution I'd use today would be

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

(credits to other author here)

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

How to get the differences between two arrays in JavaScript, including moved items

let old = [ "b", "c", "d", "e", "f", "g", "h", "i", "j" ];
let news = [ "a", "d", "c", "e", "f", "h", "i", "j" ];

let added = news.filter(item => !old.includes(item));
let removed = old.filter(item => !news.includes(item));
// find items that only changed place
let oldCommon = old.filter(item => news.includes(item));
let newCommon = news.filter(item => old.includes(item));
let moved = newCommon.filter((item, i) => item != oldCommon[i]);

console.log("added", added);
console.log("removed", removed);
console.log("moved", moved);

How to compare arrays in JavaScript?

To compare arrays, loop through them and compare every value:

Comparing arrays:

// Warn if overriding existing method
if(Array.prototype.equals)
console.warn("Overriding existing Array.prototype.equals. Possible causes: New API defines the method, there's a framework conflict or you've got double inclusions in your code.");
// attach the .equals method to Array's prototype to call it on any array
Array.prototype.equals = function (array) {
// if the other array is a falsy value, return
if (!array)
return false;

// compare lengths - can save a lot of time
if (this.length != array.length)
return false;

for (var i = 0, l=this.length; i < l; i++) {
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
// Warning - two different object instances will never be equal: {x:20} != {x:20}
return false;
}
}
return true;
}
// Hide method from for-in loops
Object.defineProperty(Array.prototype, "equals", {enumerable: false});

Usage:

[1, 2, [3, 4]].equals([1, 2, [3, 2]]) === false;
[1, "2,3"].equals([1, 2, 3]) === false;
[1, 2, [3, 4]].equals([1, 2, [3, 4]]) === true;
[1, 2, 1, 2].equals([1, 2, 1, 2]) === true;

You may say "But it is much faster to compare strings - no loops..." well, then you should note there ARE loops. First recursive loop that converts Array to string and second, that compares two strings. So this method is faster than use of string.

I believe that larger amounts of data should be always stored in arrays, not in objects. However if you use objects, they can be partially compared too.

Here's how:

Comparing objects:

I've stated above, that two object instances will never be equal, even if they contain same data at the moment:

({a:1, foo:"bar", numberOfTheBeast: 666}) == ({a:1, foo:"bar", numberOfTheBeast: 666})  //false

This has a reason, since there may be, for example private variables within objects.

However, if you just use object structure to contain data, comparing is still possible:

Object.prototype.equals = function(object2) {
//For the first loop, we only check for types
for (propName in this) {
//Check for inherited methods and properties - like .equals itself
//https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwnProperty
//Return false if the return value is different
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
//Check instance type
else if (typeof this[propName] != typeof object2[propName]) {
//Different types => not equal
return false;
}
}
//Now a deeper check using other objects property names
for(propName in object2) {
//We must check instances anyway, there may be a property that only exists in object2
//I wonder, if remembering the checked values from the first loop would be faster or not
if (this.hasOwnProperty(propName) != object2.hasOwnProperty(propName)) {
return false;
}
else if (typeof this[propName] != typeof object2[propName]) {
return false;
}
//If the property is inherited, do not check any more (it must be equa if both objects inherit it)
if(!this.hasOwnProperty(propName))
continue;

//Now the detail check and recursion

//This returns the script back to the array comparing
/**REQUIRES Array.equals**/
if (this[propName] instanceof Array && object2[propName] instanceof Array) {
// recurse into the nested arrays
if (!this[propName].equals(object2[propName]))
return false;
}
else if (this[propName] instanceof Object && object2[propName] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[propName].equals(object2[propName]))
return false;
}
//Normal value comparison for strings and numbers
else if(this[propName] != object2[propName]) {
return false;
}
}
//If everything passed, let's say YES
return true;
}

However, remember that this one is to serve in comparing JSON like data, not class instances and other stuff. If you want to compare more complicated objects, look at this answer and it's super long function.

To make this work with Array.equals you must edit the original function a little bit:

...
// Check if we have nested arrays
if (this[i] instanceof Array && array[i] instanceof Array) {
// recurse into the nested arrays
if (!this[i].equals(array[i]))
return false;
}
/**REQUIRES OBJECT COMPARE**/
else if (this[i] instanceof Object && array[i] instanceof Object) {
// recurse into another objects
//console.log("Recursing to compare ", this[propName],"with",object2[propName], " both named \""+propName+"\"");
if (!this[i].equals(array[i]))
return false;
}
else if (this[i] != array[i]) {
...

I made a little test tool for both of the functions.

Bonus: Nested arrays with indexOf and contains

Samy Bencherif has prepared useful functions for the case you're searching for a specific object in nested arrays, which are available here: https://jsfiddle.net/SamyBencherif/8352y6yw/

How to get the difference between two arrays of objects in JavaScript

Using only native JS, something like this will work:

const a = [{ value:"0", display:"Jamsheer" }, { value:"1", display:"Muhammed" }, { value:"2", display:"Ravi" }, { value:"3", display:"Ajmal" }, { value:"4", display:"Ryan" }];
const b = [{ value:"0", display:"Jamsheer", $$hashKey:"008" }, { value:"1", display:"Muhammed", $$hashKey:"009" }, { value:"2", display:"Ravi", $$hashKey:"00A" }, { value:"3", display:"Ajmal", $$hashKey:"00B" }];

// A comparer used to determine if two entries are equal.
const isSameUser = (a, b) => a.value === b.value && a.display === b.display;

// Get items that only occur in the left array,
// using the compareFunction to determine equality.
const onlyInLeft = (left, right, compareFunction) =>
left.filter(leftValue =>
!right.some(rightValue =>
compareFunction(leftValue, rightValue)));

const onlyInA = onlyInLeft(a, b, isSameUser);
const onlyInB = onlyInLeft(b, a, isSameUser);

const result = [...onlyInA, ...onlyInB];

console.log(result);

Get the difference between two arrays in Laravel

If you need to retrieve only the differences from the $category.

You can use PHP inbuild function array_diff() function.

$differenceArray = array_diff($category, $TagNames);

Keep in mind that, it will not display the difference of $TagNames.

To retrieve all the difference, you can retrieve the first difference and second difference and use array_merge() function to merge it together.

$differenceArray1 = array_diff($category, $TagNames);
$differenceArray2 = array_diff($TagNames, $category);

$mergeDifference = array_merge($differenceArray1, $differenceArray2);

difference between two arrays

Note: this answer will return the values in $array2 that are not present in $array1, it will not return the values in $array1 that are not in $array2.

$diff = array_diff($array2, $array1);

array_diff()

Find difference between two arrays

This will find the objects in arr1 that are not in arr2 based on the id attribute.

var arr1 = [ { "id": "1" }, { "id": "2" }, { "id": "3" } ];var arr2 = [ { "id": "1" }, { "id": "2" } ];var result = arr1.filter(o1 => arr2.filter(o2 => o2.id === o1.id).length === 0);console.log(result);

Typescript difference between two arrays

There are probably a lot of ways, for example using the Array.prototype.filter():

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

let missing = a1.filter(item => a2.indexOf(item) < 0);
console.log(missing); // ["e", "f", "g"]

(code in playground)


Edit

The filter function runs over the elements of a1 and it reduce it (but in a new array) to elements who are in a1 (because we're iterating over it's elements) and are missing in a2.

Elements in a2 which are missing in a1 won't be included in the result array (missing) as the filter function doesn't iterate over the a2 elements:

var a1 = ['a', 'b', 'c', 'd', 'e', 'f', 'g'];
var a2 = ['a', 'b', 'c', 'd', 'z', 'hey', 'there'];

let missing = a1.filter(item => a2.indexOf(item) < 0);
console.log(missing); // still ["e", "f", "g"]

(code in playground)

Get the difference of arrays in ES6?

You can use filter() and find() to return filtered array.