user7889681
user7889681

Reputation:

How to check whether two arrays of objects are different, disregarding the order?

Case 1

let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}]

isDifferent(x,y) must return true.

Case 2

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

isDifferent(a,b) must return false.

Case 3

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]

isDifferent(a,b) must return false.

I tried using isMatch function of lodash

 isDifferent(arr1, arr2) {
        return !isMatch(arr1, arr2);
    }

Case 1 and Case 3 works as expected. But in Case 2, the function returns true. Note that only the order of the objects in the array is interchanged.

I cannot check based on _id since the two arrays that I compare may not have _id at all.

let p=[{name:"abc",age:"2"},{name:"def",age:"2"}]
let q=[{name:"abc",age:"3"},{name:"def",age:"4"}]

The arrays could be like this. But what I can guarantee is the objects will have same properties in both arrays

Upvotes: 3

Views: 1152

Answers (4)

Akrion
Akrion

Reputation: 18515

Interesting question. Here is a solution which works by sorting the arrays and then using !_.isEqual to compare them:

let x=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}]

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]


const isDifferent = (a, b) => {
  const sortArray = (arr) => _.sortBy(arr, ['id', 'name'])
  return !_.isEqual(sortArray(a), sortArray(b))
}

console.log('x & y: ', isDifferent(x,y))
console.log('a & b: ', isDifferent(a,b))
console.log('p & q: ', isDifferent(p,q))
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Upvotes: 0

Sangram Nandkhile
Sangram Nandkhile

Reputation: 18192

I'll use isEqual() method.

// False
    let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let y= [{_id:"1",name:"abc"},{_id:"3",name:"def"}]

    // true
    let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}]

    //true
    let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
    let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}]

    function compare(a, b) {
    var key = Object.keys(a)[0];
    if (a[key] < b[key])
        return -1;
    if (a[key] > b[key])
        return 1;
    return 0;
}

function sortObject(o) {
    var sorted = {},
        key, a = [];
    for (key in o) {
        if (o.hasOwnProperty(key)) {
            a.push(key);
        }
    }
    a.sort();
    for (key = 0; key < a.length; key++) {
        sorted[a[key]] = o[a[key]];
    }
    return sorted;
}

function isEqual(array1, array2) {
    array1 = array1.map(x => sortObject(x)).sort(compare);
    array2 = array2.map(x => sortObject(x)).sort(compare);
    if (JSON.stringify(array1) === JSON.stringify(array2))
        return true;
    else return false;
}

console.log('Are x and y equal ==> ' + isEqual(x, y));
console.log('Are a and b equal ==> ' + isEqual(a, b));
console.log('Are p and q equal ==> ' + isEqual(p, q));

Upvotes: 0

ryeballar
ryeballar

Reputation: 30088

You can use lodash#xorWith with lodash#isEqual as the comparator function to get an array of items that are different from argument a and b. We can infer that a and b are different based on the length of the resulting array.

function isDifferent(a, b) {
  return _.xorWith(a, b, _.isEqual).length > 0;
}

let x =[{_id:"1",name:"abc"},{_id:"2",name:"def"}]
let y=[{_id:"1",name:"abc"},{_id:"3",name:"def"}];

let a=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];
let b=[{_id:"2",name:"def"},{_id:"1",name:"abc"}];

let p=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];
let q=[{_id:"1",name:"abc"},{_id:"2",name:"def"}];

console.log(isDifferent(x, y));

console.log(isDifferent(a, b));

console.log(isDifferent(p, q));

function isDifferent(a, b) {
  return _.xorWith(a, b, _.isEqual).length > 0;
}
.as-console-wrapper{min-height:100%;top:0}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.10/lodash.min.js"></script>

Upvotes: 1

S Gupta
S Gupta

Reputation: 1587

Use the isEuqual method provided by lodash as it performs a deep comparison between two values to determine if they are equivalent.

_.isEqual(array1, array2);

This method supports comparing arrays, array buffers, booleans, date objects, error objects, maps, numbers, Object objects, regexes, sets, strings, symbols, and typed arrays. Object objects are compared by their own, not inherited, enumerable properties. Functions and DOM nodes are compared by strict equality, i.e. ===.

Upvotes: 1

Related Questions