-2

I have 2 arrays of objects which contain same properties, but depending on situation they can have 1-50 properties. I need to get difference between those 2

Array 1:

[
  {
    "prop1": 1,
    "prop2": 2
  },
  {
    "prop1": 4,
    "prop2": 4
  },
  {
    "prop1": 3,
    "prop2": 7
  },
  {
    "prop1": 1,
    "prop2": 3
  }
]

Array 2:

[
  {
    "prop1": 1,
    "prop2": 2
  },
  {
    "prop1": 4,
    "prop2": 4
  }
]

I tried with underscore's difference function but it doesn't work well in this scenario. I was thinking of getting object keys, sorting it and hasnhing the objects.That I can compare but I need to get it back into original format. And since these arrays can have up to 5000 object it seems costly.

Is there an effecient solution?

Edit: I have seen the question Difference between two array of objects in JavaScript but that example has static number of properties on which he filters the arrays. That is not the case; I do not know names, nor quantity of properties.

CountGradsky
  • 268
  • 2
  • 4
  • 15
  • Possible duplicate of [Difference between two array of objects in JavaScript](https://stackoverflow.com/questions/21987909/difference-between-two-array-of-objects-in-javascript) – Rahul Nov 17 '17 at 10:04
  • Refer this answer [link](https://stackoverflow.com/a/21988185/6556397) – Rahul Nov 17 '17 at 10:04
  • please add the wanted result. are the properties always the same? – Nina Scholz Nov 17 '17 at 10:28
  • Properties vary but they are the same in both arrays. Every item in each array has different combination of properties. – CountGradsky Nov 17 '17 at 15:08

1 Answers1

1

You could take some hash tables and get the keys first and then the values and check the hash of the other array and filter the result.

This proposal returns the symetriccal difference of the two arrays.

function getDifference(a, b) {
    function getKeyValue(object) {
        var keys = Object.keys(object).sort();
        return {
            key: keys.join('|'),
            value: keys.map(function (k) { return object[k]; }).join('|')
        };
    }

    function setHash(hash, kv) {
        hash[kv.key] = hash[kv.key] || {};
        hash[kv.key][kv.value] = true;
    }

    function isHash(hash, kv) {
        return hash[kv.key] && hash[kv.key][kv.value];
    }

    var hashA = Object.create(null),
        hashB = Object.create(null),
        result;

    b.forEach(function (o) {
        var kv = getKeyValue(o);
        setHash(hashB, kv);
    });

    return Array.prototype.concat(
        [],
        array1.filter(function (o) {
            var kv = getKeyValue(o);
            setHash(hashA, kv);
            return !isHash(hashB, kv);
        }),
        array2.filter(function (o) {
            var kv = getKeyValue(o);
            return !isHash(hashA, kv);
        })
    );
}

var array1 = [{ prop1: 1, prop2: 2 }, { prop1: 4, prop2: 4 }, { prop1: 3, prop2: 7 }, { prop1: 1, prop2: 3 }, { prop2: 3 }],
    array2 = [{ prop1: 1, prop2: 2 }, { prop1: 4, prop2: 4 }, { prop1: 4 }];

console.log(getDifference(array1, array2));
.as-console-wrapper { max-height: 100% !important; top: 0; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392