As serialization doesn't work generally [only when the order of properties matches: JSON.stringify[{a:1,b:2}] !== JSON.stringify[{b:2,a:1}]
] you have to check the count of properties and compare each property as well:
const objectsEqual = [o1, o2] =>
Object.keys[o1].length === Object.keys[o2].length
&& Object.keys[o1].every[p => o1[p] === o2[p]];
const obj1 = { name: 'John', age: 33};
const obj2 = { age: 33, name: 'John' };
const obj3 = { name: 'John', age: 45 };
console.log[objectsEqual[obj1, obj2]]; // true
console.log[objectsEqual[obj1, obj3]]; // false
If you need a deep comparison, you can call the function recursively:
const obj1 = { name: 'John', age: 33, info: { married: true, hobbies: ['sport', 'art'] } };
const obj2 = { age: 33, name: 'John', info: { hobbies: ['sport', 'art'], married: true } };
const obj3 = { name: 'John', age: 33 };
const objectsEqual = [o1, o2] =>
typeof o1 === 'object' && Object.keys[o1].length > 0
? Object.keys[o1].length === Object.keys[o2].length
&& Object.keys[o1].every[p => objectsEqual[o1[p], o2[p]]]
: o1 === o2;
console.log[objectsEqual[obj1, obj2]]; // true
console.log[objectsEqual[obj1, obj3]]; // false
Then it's easy to use this function to compare objects in arrays:
const arr1 = [obj1, obj1];
const arr2 = [obj1, obj2];
const arr3 = [obj1, obj3];
const arraysEqual = [a1, a2] =>
a1.length === a2.length && a1.every[[o, idx] => objectsEqual[o, a2[idx]]];
console.log[arraysEqual[arr1, arr2]]; // true
console.log[arraysEqual[arr1, arr3]]; // false
answered Mar 20, 2019 at 8:22
ttulkattulka
9,1134 gold badges37 silver badges48 bronze badges
11
EDIT: You cannot overload operators in current, common browser-based implementations of JavaScript interpreters.
To answer the original question, one way you could do this, and mind you, this is a bit of a hack, simply serialize the two arrays to JSON and then compare the two JSON strings. That would simply tell you if the arrays are different, obviously you could do this to each of the objects within the arrays as well to see which ones were different.
Another option is to use a library which has some nice facilities for comparing objects - I use and recommend MochiKit.
EDIT: The answer kamens gave deserves consideration as well, since a single function to compare two given objects would be much smaller than any library to do what I suggest [although my suggestion would certainly work well enough].
Here is a naïve implemenation that may do just enough for you - be aware that there are potential problems with this implementation:
function objectsAreSame[x, y] {
var objectsAreSame = true;
for[var propertyName in x] {
if[x[propertyName] !== y[propertyName]] {
objectsAreSame = false;
break;
}
}
return objectsAreSame;
}
The assumption is that both objects have the same exact list of properties.
Oh, and it is probably obvious that, for better or worse, I belong to the only-one-return-point camp. :]
answered Aug 26, 2008 at 1:39
Jason BuntingJason Bunting
57.2k14 gold badges99 silver badges93 bronze badges
4
Honestly, with 8 objects max and 8 properties max per object, your best bet is to just traverse each object and make the comparisons directly. It'll be fast and it'll be easy.
If you're going to be using these types of comparisons often, then I agree with Jason about JSON serialization...but otherwise there's no need to slow down your app with a new library or JSON serialization code.
answered Aug 26, 2008 at 12:52
kamenskamens
11.6k6 gold badges44 silver badges46 bronze badges
1
I know this is an old question and the answers provided work fine ... but this is a bit shorter and doesn't require any additional libraries [ i.e. JSON ]:
function arraysAreEqual[ary1,ary2]{
return [ary1.join[''] == ary2.join['']];
}
Mr.Wizard
24k5 gold badges42 silver badges120 bronze badges
answered May 20, 2011 at 15:23
jwoodjwood
3472 silver badges6 bronze badges
8
I have worked a bit on a simple algorithm to compare contents of two objects and return an
intelligible list of difference. Thought I would share. It borrows some ideas for jQuery, namely the map
function implementation and the object and array type checking.
It returns a list of "diff objects", which are arrays with the diff info. It's very simple.
Here it is:
// compare contents of two objects and return a list of differences
// returns an array where each element is also an array in the form:
// [accessor, diffType, leftValue, rightValue ]
//
// diffType is one of the following:
// value: when primitive values at that index are different
// undefined: when values in that index exist in one object but don't in
// another; one of the values is always undefined
// null: when a value in that index is null or undefined; values are
// expressed as boolean values, indicated wheter they were nulls
// type: when values in that index are of different types; values are
// expressed as types
// length: when arrays in that index are of different length; values are
// the lengths of the arrays
//
function DiffObjects[o1, o2] {
// choose a map[] impl.
// you may use $.map from jQuery if you wish
var map = Array.prototype.map?
function[a] { return Array.prototype.map.apply[a, Array.prototype.slice.call[arguments, 1]]; } :
function[a, f] {
var ret = new Array[a.length], value;
for [ var i = 0, length = a.length; i < length; i++ ]
ret[i] = f[a[i], i];
return ret.concat[];
};
// shorthand for push impl.
var push = Array.prototype.push;
// check for null/undefined values
if [[o1 == null] || [o2 == null]] {
if [o1 != o2]
return [["", "null", o1!=null, o2!=null]];
return undefined; // both null
}
// compare types
if [[o1.constructor != o2.constructor] ||
[typeof o1 != typeof o2]] {
return [["", "type", Object.prototype.toString.call[o1], Object.prototype.toString.call[o2] ]]; // different type
}
// compare arrays
if [Object.prototype.toString.call[o1] == "[object Array]"] {
if [o1.length != o2.length] {
return [["", "length", o1.length, o2.length]]; // different length
}
var diff =[];
for [var i=0; i {
if [o2 === null && o1 !== null] return false;
return o1 !== null && typeof o1 === 'object' && Object.keys[o1].length > 0 ?
Object.keys[o1].length === Object.keys[o2].length &&
Object.keys[o1].every[p => objectsEqual[o1[p], o2[p]]]
: [o1 !== null && Array.isArray[o1] && Array.isArray[o2] && !o1.length &&
!o2.length] ? true : o1 === o2;
}
answered Feb 11, 2021 at 0:39
WolframWolfram
411 silver badge3 bronze badges
1
Here is my attempt, using Node's assert module + npm package object-hash.
I suppose that you would like to check if two arrays contain the same objects, even if those objects are ordered differently between the two arrays.
var assert = require['assert'];
var hash = require['object-hash'];
var obj1 = {a: 1, b: 2, c: 333},
obj2 = {b: 2, a: 1, c: 444},
obj3 = {b: "AAA", c: 555},
obj4 = {c: 555, b: "AAA"};
var array1 = [obj1, obj2, obj3, obj4];
var array2 = [obj3, obj2, obj4, obj1]; // [obj3, obj3, obj2, obj1] should work as well
// calling assert.deepEquals[array1, array2] at this point FAILS [throws an AssertionError]
// even if array1 and array2 contain the same objects in different order,
// because array1[0].c !== array2[0].c
// sort objects in arrays by their hashes, so that if the arrays are identical,
// their objects can be compared in the same order, one by one
var array1 = sortArrayOnHash[array1];
var array2 = sortArrayOnHash[array2];
// then, this should output "PASS"
try {
assert.deepEqual[array1, array2];
console.log["PASS"];
} catch [e] {
console.log["FAIL"];
console.log[e];
}
// You could define as well something like Array.prototype.sortOnHash[]...
function sortArrayOnHash[array] {
return array.sort[function[a, b] {
return hash[a] > hash[b];
}];
}
answered Mar 20, 2017 at 12:48
Frosty ZFrosty Z
21.6k11 gold badges81 silver badges110 bronze badges
My practice implementation with sorting, tested and working.
const obj1 = { name: 'John', age: 33};
const obj2 = { age: 33, name: 'John' };
const obj3 = { name: 'John', age: 45 };
const equalObjs = [ obj1, obj2 ] => {
let keyExist = false;
for [ const [key, value] of Object.entries[obj1] ] {
// Search each key in reference object and attach a callback function to
// compare the two object keys
if[ Object.keys[obj2].some[ [ e ] => e == key ] ] {
keyExist = true;
}
}
return keyExist;
}
console.info[ equalObjs[ obj1, obj2 ] ];
Compare your arrays
// Sort Arrays
var arr1 = arr1.sort[[ a, b ] => {
var fa = Object.keys[a];
var fb = Object.keys[b];
if [fa < fb] {
return -1;
}
if [fa > fb] {
return 1;
}
return 0;
}];
var arr2 = arr2.sort[[ a, b ] => {
var fa = Object.keys[a];
var fb = Object.keys[b];
if [fa < fb] {
return -1;
}
if [fa > fb] {
return 1;
}
return 0;
}];
const equalArrays = [ arr1, arr2 ] => {
// If the arrays are different length we an eliminate immediately
if[ arr1.length !== arr2.length ] {
return false;
} else if [ arr1.every[[ obj, index ] => equalObjs[ obj, arr2[index] ] ] ] {
return true;
} else {
return false;
}
}
console.info[ equalArrays[ arr1, arr2 ] ];
answered May 11, 2021 at 15:33
Shawn WShawn W
5164 silver badges13 bronze badges
Please try this one:
function used_to_compare_two_arrays[a, b]
{
// This block will make the array of indexed that array b contains a elements
var c = a.filter[function[value, index, obj] {
return b.indexOf[value] > -1;
}];
// This is used for making comparison that both have same length if no condition go wrong
if [c.length !== a.length] {
return 0;
} else{
return 1;
}
}
c0deNinja
3,9201 gold badge28 silver badges45 bronze badges
answered Aug 11, 2014 at 6:51
1
The objectsAreSame
function mentioned in @JasonBunting's
answer works fine for me. However, there's a little problem: If x[propertyName]
and y[propertyName]
are objects [typeof x[propertyName] == 'object'
], you'll need to call the function recursively in order to compare them.
answered Mar 16, 2009 at 6:40
I am sharing my compare function implementation as it might be helpful for others:
/*
null AND null // true
undefined AND undefined // true
null AND undefined // false
[] AND [] // true
[1, 2, 'test'] AND ['test', 2, 1] // true
[1, 2, 'test'] AND ['test', 2, 3] // false
[undefined, 2, 'test'] AND ['test', 2, 1] // false
[undefined, 2, 'test'] AND ['test', 2, undefined] // true
[[1, 2], 'test'] AND ['test', [2, 1]] // true
[1, 'test'] AND ['test', [2, 1]] // false
[[2, 1], 'test'] AND ['test', [2, 1]] // true
[[2, 1], 'test'] AND ['test', [2, 3]] // false
[[[3, 4], 2], 'test'] AND ['test', [2, [3, 4]]] // true
[[[3, 4], 2], 'test'] AND ['test', [2, [5, 4]]] // false
[{x: 1, y: 2}, 'test'] AND ['test', {x: 1, y: 2}] // true
1 AND 1 // true
{test: 1} AND ['test', 2, 1] // false
{test: 1} AND {test: 1} // true
{test: 1} AND {test: 2} // false
{test: [1, 2]} AND {test: [1, 2]} // true
{test: [1, 2]} AND {test: [1]} // false
{test: [1, 2], x: 1} AND {test: [1, 2], x: 2} // false
{test: [1, { z: 5 }], x: 1} AND {x: 1, test: [1, { z: 5}]} // true
{test: [1, { z: 5 }], x: 1} AND {x: 1, test: [1, { z: 6}]} // false
*/
function is_equal[x, y] {
const
arr1 = x,
arr2 = y,
is_objects_equal = function [obj_x, obj_y] {
if [![
typeof obj_x === 'object' &&
Object.keys[obj_x].length > 0
]]
return obj_x === obj_y;
return Object.keys[obj_x].length === Object.keys[obj_y].length &&
Object.keys[obj_x].every[p => is_objects_equal[obj_x[p], obj_y[p]]];
}
;
if [![ Array.isArray[arr1] && Array.isArray[arr2] ]]
return [
arr1 && typeof arr1 === 'object' &&
arr2 && typeof arr2 === 'object'
]
? is_objects_equal[arr1, arr2]
: arr1 === arr2;
if [arr1.length !== arr2.length]
return false;
for [const idx_1 of arr1.keys[]]
for [const idx_2 of arr2.keys[]]
if [
[
Array.isArray[arr1[idx_1]] &&
this.is_equal[arr1[idx_1], arr2[idx_2]]
] ||
is_objects_equal[arr1[idx_1], arr2[idx_2]]
]
{
arr2.splice[idx_2, 1];
break;
}
return !arr2.length;
}
Ruli
2,44112 gold badges27 silver badges35 bronze badges
answered Nov 9, 2021 at 10:01
0
using _.some
from lodash: //lodash.com/docs/4.17.11#some
const array1AndArray2NotEqual =
_.some[array1, [a1, idx] => a1.key1 !== array2[idx].key1
|| a1.key2 !== array2[idx].key2
|| a1.key3 !== array2[idx].key3];
adiga
32.2k8 gold badges55 silver badges78 bronze badges
answered Jan 3, 2019 at 23:24
0
There`s my solution. It will compare arrays which also have objects and arrays. Elements can be stay in any positions. Example:
const array1 = [{a: 1}, {b: 2}, { c: 0, d: { e: 1, f: 2, } }, [1,2,3,54]];
const array2 = [{a: 1}, {b: 2}, { c: 0, d: { e: 1, f: 2, } }, [1,2,3,54]];
const arraysCompare = [a1, a2] => {
if [a1.length !== a2.length] return false;
const objectIteration = [object] => {
const result = [];
const objectReduce = [obj] => {
for [let i in obj] {
if [typeof obj[i] !== 'object'] {
result.push[`${i}${obj[i]}`];
} else {
objectReduce[obj[i]];
}
}
};
objectReduce[object];
return result;
};
const reduceArray1 = a1.map[item => {
if [typeof item !== 'object'] return item;
return objectIteration[item].join[''];
}];
const reduceArray2 = a2.map[item => {
if [typeof item !== 'object'] return item;
return objectIteration[item].join[''];
}];
const compare = reduceArray1.map[item => reduceArray2.includes[item]];
return compare.reduce[[acc, item] => acc + Number[item]] === a1.length;
};
console.log[arraysCompare[array1, array2]];
answered Feb 14, 2021 at 19:07
not sure about the performance ... will have to test on big objects .. however, this works great for me.. the advantage it has compared to the other solutions is, the objects/array do not have to be in the same order ....
it practically takes the first object in the first array, and scans the second array for every objects .. if it's a match, it will proceed to another
there is absolutely a way for optimization but it's working :]
thx to @ttulka I got inspired by his work ... just worked on it a little bit
const objectsEqual = [o1, o2] => {
let match = false
if[typeof o1 === 'object' && Object.keys[o1].length > 0] {
match = [Object.keys[o1].length === Object.keys[o2].length && Object.keys[o1].every[p => objectsEqual[o1[p], o2[p]]]]
}else {
match = [o1 === o2]
}
return match
}
const arraysEqual = [a1, a2] => {
let finalMatch = []
let itemFound = []
if[a1.length === a2.length] {
finalMatch = []
a1.forEach[ i1 => {
itemFound = []
a2.forEach[ i2 => {
itemFound.push[objectsEqual[i1, i2]]
}]
finalMatch.push[itemFound.some[ i => i === true]]
}]
}
return finalMatch.every[i => i === true]
}
const ar1 = [
{ id: 1, name: "Johnny", data: { body: "Some text"}},
{ id: 2, name: "Jimmy"}
]
const ar2 = [
{name: "Jimmy", id: 2},
{name: "Johnny", data: { body: "Some text"}, id: 1}
]
console.log["Match:",arraysEqual[ar1, ar2]]
jsfiddle: //jsfiddle.net/x1pubs6q/
or just use lodash :]]]]
const _ = require['lodash']
const isArrayEqual = [x, y] => {
return _.isEmpty[_.xorWith[x, y, _.isEqual]];
};
answered Dec 9, 2021 at 8:14
Mr.PMr.P
1,0591 gold badge17 silver badges38 bronze badges
This is work for me to compare two array of objects without taking into consideration the order of the items
const collection1 = [
{ id: "1", name: "item 1", subtitle: "This is a subtitle", parentId: "1" },
{ id: "2", name: "item 2", parentId: "1" },
{ id: "3", name: "item 3", parentId: "1" },
]
const collection2 = [
{ id: "3", name: "item 3", parentId: "1" },
{ id: "2", name: "item 2", parentId: "1" },
{ id: "1", name: "item 1", subtitle: "This is a subtitle", parentId: "1" },
]
const contains = [arr, obj] => {
let i = arr.length;
while [i--] {
if [JSON.stringify[arr[i]] === JSON.stringify[obj]] {
return true;
}
}
return false;
}
const isEqual = [obj1, obj2] => {
let n = 0
if [obj1.length !== obj2.length] {
return false;
}
for [let i = 0; i < obj1.length; i++] {
if [contains[obj2, obj1[i]]] {
n++
}
}
return n === obj1.length
}
console.log[isEqual[collection1,collection2]]
if you take into consideration the order of the items use built in function in lodash isEqual
answered Jun 20 at 18:36
2
If you stringify them...
type AB = {
nome: string;
}
const a: AB[] = [{ nome: 'Célio' }];
const b: AB[] = [{ nome: 'Célio' }];
console.log[a === b]; // false
console.log[JSON.stringify[a] === JSON.stringify[b]]; // true
answered Jul 3 at 12:01
1