0

Similar to this question and this question, i have an array of objects which I want to compare and then get the difference between these two. Sadly, my objects do not contain a ID (And at the state where I need to call the function, I also can't just give an ID to the Objects.).The examples i linked above rely on using the objects id for comparison, so I can't use these solutions. My arrays look like this:

var array1 = [{person1ID: 46, person2ID: 47, value: "test"}, {person1ID: 38, person2ID: 56, value: "test2"}];
var array2 = [{person1ID: 46, person2ID: 47, value: "test"}];

In this example, I would like to get the Object {person1ID: 38, person2ID: 56, value: "test2"}, as this is in array1 but not in array2.

Is there any way I can compare the two arrays and get the difference if the objects in the array do not have an ID?

Nils Schlüter
  • 1,418
  • 1
  • 19
  • 30

4 Answers4

1

You could use a nested approach which check every object of the first array with every object of the second array, property wise.

function getDifference(array1, array2) {
    var keys = ['person1ID', 'person2ID', 'value'];

    return array1.filter(function (a) {
        return !array2.some(function (b) {
            return keys.every(function (k) {
                return a[k] === b[k];
            });
        });    
    });
}

console.log(getDifference(
    [{person1ID: 46, person2ID: 47, value: "test"}, {person1ID: 38, person2ID: 56, value: "test2"}],
    [{person1ID: 46, person2ID: 47, value: "test"}]
));
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
  • It seems to me the best solution, but why don't you use `find` instead of `some`? Eventually one match is enough. Am I Wrong? – Marco Luzzara Jul 28 '17 at 13:53
  • @MarcoLuzzara, find returns the found item, which is here not necessary, because we need a boolean value. `some` matches best for this purpose. – Nina Scholz Jul 28 '17 at 18:39
0

If you have same properties in all objects then you can do something like this

var array1 = [{person1ID: 46, person2ID: 47, value: "test"}, {person1ID: 38, person2ID: 56, value: "test2"}];
var array2 = [{person1ID: 46, person2ID: 47, value: "test"}];

function compareArrays(arr2){
 return function(current){
  return arr2.filter(function(arr1){
   return arr1.value == current.value && arr1.person1ID == current.person1ID && arr1.person2ID == current.person2ID;
  }).length == 0;
 }
}

var result = array1.filter(compareArrays(array2))
console.log(result)
Niroda
  • 320
  • 1
  • 3
  • 13
0
var result=array1.filter(function(el,i){
  return !array2.some( 
     el2=>Object.keys(el).every(
        key=>el2[key]&&el[key]===el2[key]
     )
  )
});

Simply check that theres at least some el in array2 where every key equals the object in array1.

Jonas Wilms
  • 132,000
  • 20
  • 149
  • 151
0

Here is my take on this problem:

function objectsFunctionallyIdentical(a, b) {
    //If they are the same object
    if (a == b) {
        return true;
    }
    //get keys
    var keysA = Object.keys(a);
    var keysB = Object.keys(b);
    //If not the same amount of keys, return false
    if (keysA.length != keysB.length) {
        return false;
    }
    //get unique keys
    var uniqueKeys = keysA
        .concat(keysB)
        .filter(function (value, index, arr) {
        return (arr.indexOf(value) == index);
    });
    //By key loop
    for (var keyIndex = 0; keyIndex < uniqueKeys.length; keyIndex++) {
        var key = uniqueKeys[keyIndex];
        //If key undefined, return false
        if (a[key] == void 0 || b[key] == void 0) {
            return false;
        }
        //If key inheritance differs, return false
        if (a.hasOwnProperty(key) != b.hasOwnProperty(key)) {
            return false;
        }
        //If key mismatch, return false
        if (a[key] != b[key]) {
            return false;
        }
    }
    //All tests passed, return true
    return true;
}
function listOfObjectsFunctionallyIdentical(lista, listb) {
    //list of suspects
    var mistMatches = [];
    //loop list a
    for (var index = 0; index < lista.length; index++) {
        var objA = lista[index];
        //check for occurrence in list b
        if (listb.some(function (objB) {
            return objectsFunctionallyIdentical(objB, objA);
        })) {
            continue;
        }
        //add to mismatches if no occurrence in list b
        mistMatches.push(objA);
    }
    //loop list b
    for (var index = 0; index < listb.length; index++) {
        var objB = listb[index];
        //check for occurrence in list a
        if (lista.some(function (objA) {
            return objectsFunctionallyIdentical(objB, objA);
        })) {
            continue;
        }
        //add to mismatches if no occurrence in list a
        mistMatches.push(objB);
    }
    return mistMatches;
}
//TEST
var obja = { person1ID: 1, person2ID: 20, value: "test" };
var objb = { person1ID: 2, person2ID: 20, value: "test" };
var objc = { person1ID: 3, person2ID: 20, value: "test" };
var objd = { person1ID: 4, person2ID: 20, value: "test" };
var obje = { person1ID: 1, person2ID: 20, value: "test" };
var arr1 = [obja, objb];
var arr2 = [obja, objb, objc];
var arr3 = [obja, objb, objd];
console.log(objectsFunctionallyIdentical(obja, obja)); //TRUE, they are the same
console.log(objectsFunctionallyIdentical(obja, objb)); //FALSE, they are different
console.log(objectsFunctionallyIdentical(obja, obje)); //TRUE, they are alike
console.log(listOfObjectsFunctionallyIdentical(arr1, arr2)); //1 mismatch (objc)
console.log(listOfObjectsFunctionallyIdentical(arr2, arr2)); //0 mismatch
console.log(listOfObjectsFunctionallyIdentical(arr2, arr3)); //2 mismatch (objc,objd)
Emil S. Jørgensen
  • 6,216
  • 1
  • 15
  • 28