Akshay Maldhure
Akshay Maldhure

Reputation: 857

Compare two arrays containing objects including other objects, arrays, etc

Look at these examples of array comparative code:

// example-1
let array1 = ['a', 'b'];
let array2 = ['a', 'b'];
console.log(array1.equals(array2)); // returns true

// example-2
let array1 = ['a', 'b', 1];
let array2 = ['a', 'b', 1];
console.log(array1.equals(array2)); // returns true

// example-3
let array1 = ['a', 'b', {'a': 1, 'b': 2}];
let array2 = ['a', 'b', {'b': 2, 'a', 1}];
console.log(array1.equals(array2)); // returns false

I'm looking for a way to compare the arrays containing objects in them, but irrespective of the order of elements in a nested object, like mentioned in the example-3 above.

Upvotes: 1

Views: 107

Answers (4)

Jack Bashford
Jack Bashford

Reputation: 44107

You should JSON.stringify() the arrays and compare them like so:

var arr1 = ['a', 'b', {'a': 1}];
var arr2 = ['a', 'b', {'a': 1}];
console.log(JSON.stringify(array1) == JSON.stringify(array2)); 

This works because it converts arrays of objects into a much simpler comparative state (JSON strings). This will only work if the arrays contain their properties in the same ordered in the OP's example.

Upvotes: 2

Mark
Mark

Reputation: 92440

You can just write a function the will recursively check until it gets down to primitives. For example:

function deepEqual(o1, o2){
    if (Array.isArray(o1)) {
        return Array.isArray(o2)
               && o1.length === o2.length
               && o1.every((item, idx) => deepEqual(item, o2[idx]))
    }
    if (typeof(o1) == 'object' && o1 != null){ // (typeof null == 'object)
        return typeof(o2) == 'object'
               && o2 != null
               && deepEqual(Object.entries(o1)
                  .sort((a,b) => a[0].localeCompare(b[0])),Object.entries(o2).sort((a,b) => a[0].localeCompare(b[0])))
    }
    return o1 === o2
}

//Object order doesn't matter
let ob1 = [1, 2, {a: "test", b:"hello"}, 4]
let ob2 = [1, 2, {b:"hello", a: "test", }, 4]

console.log(deepEqual(ob1, ob2))

ob1 = [1, 2, {a: "test", b:"hello"}, 4]
ob2 = [1, 2, {b:"hello", a: "non-test", }, 4]

console.log(deepEqual(ob1, ob2))

// array order matters:
ob1 = [2, 1, {a: "test", b:"hello"}, 4]
ob2 = [1, 2, {b:"hello", a: "test", }, 4]

console.log(deepEqual(ob1, ob2))

console.log(deepEqual("test", "test"))

console.log(deepEqual(null, {a:"test"}))

// etc.

Upvotes: 0

sadrzadehsina
sadrzadehsina

Reputation: 1349

underscore way:

_.isEqual(array1, array2) 

Upvotes: 1

Giulio Bambini
Giulio Bambini

Reputation: 4755

You can use JSON.stringify() to get the JSON string and compare them with ===:

let array1 = ['a', 'b', {'a': 1}];
let array2 = ['a', 'b', {'a': 1}];
console.log(JSON.stringify(array1) === JSON.stringify(array2)); // returns true

Upvotes: 1

Related Questions