-1

Using jQuery I would like to compare 2 objects:

sourceArray:

var origArray = [{
    "Name": "Single",
    "URL": "xxx",
    "ID": 123
},
{
    "Name": "Double",
    "URL": "yyy",
    "ID":  345
},
{
    "Name": "Family",
    "URL": "zzz",
    "ID": 567
}];

destination array

var destArray = [{
    "Name": "Single",
    "URL": "xxx",
    "ID": 123
},
{
    "Name": "Double",
    "URL": "yyy",
    "ID":  888
},
{
    "Name": "Family",
    "URL": "zzz",
    "ID": 567
}];

What I would like to do, is compare the target object with the source object based on the ID and find the mis-matched entries with a description on the resultant object. So the result will look like this:

var resultArray = [{
    "Name": "Double",
    "URL": "yyy",
    "ID":  888,
    "desc": "missing in source" 
},
{
    "Name": "Double",
    "URL": "yyy",
    "ID": 345,
    "desc": "missing in destination"
}];

Any quick help is really appreciated.

Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
Deepak Ranjan Jena
  • 437
  • 5
  • 12
  • 23

5 Answers5

3

This isn't a good use of jQuery, but here is some vanilla javascript that does what you want.

function objDiff(array1, array2) {
    var resultArray = []

    array2.forEach(function(destObj) {
        var check = array1.some(function(origObj) {
            if(origObj.ID == destObj.ID) return true
        })
        if(!check) {
            destObj.desc = 'missing in source'
            resultArray.push(destObj)
        }
    })

    array1.forEach(function(origObj) {
        var check = array2.some(function(destObj) {
            if(origObj.ID == destObj.ID) return true
        })
        if(!check) {
            origObj.desc = 'missing in destination'
            resultArray.push(origObj)
        }
    })

    return resultArray
}

https://jsfiddle.net/9gaxsLbz/1/

0

If you are wanting to dedupe your array, this will work:

var merged = origArray.concat(destArray);
var unique = merged.filter(function(item) {
    return ~this.indexOf(item.ID) ? false : this.push(item.ID);
}, []);

Fiddle: https://jsfiddle.net/Ljzor9c6/

If you are only wanting items that were duped, you can easily invert the condition:

var merged = origArray.concat(destArray);
var dupes  = merged.filter(function(item) {
    return ~this.indexOf(item.ID) ? true : !this.push(item.ID);
}, []);
Rob M.
  • 35,491
  • 6
  • 51
  • 50
0

You can loop through the items in the first array and put the ID's in a map, then loop through the items in the second array and remove the matching ID's and add the missing.

Then just loop through the map to create the objects in the resulting array:

var origArray = [{
    "Name": "Single",
    "URL": "xxx",
    "ID": 123
},
{
    "Name": "Double",
    "URL": "yyy",
    "ID":  345
},
{
    "Name": "Family",
    "URL": "zzz",
    "ID": 567
}];

var destArray = [{
    "Name": "Single",
    "URL": "xxx",
    "ID": 123
},
{
    "Name": "Double",
    "URL": "yyy",
    "ID":  888
},
{
    "Name": "Family",
    "URL": "zzz",
    "ID": 567
}];

var map = {};
for (var i = 0; i < origArray.length; i++) {
    map[origArray[i].ID] = 'source';
}
for (var i = 0; i < destArray.length; i++) {
    var id = destArray[i].ID;
    if (id in map) {
        delete map[id];
    } else {
        map[id] = 'destination';
    }
}
var resultArray = [];
for (key in map) {
    var arr = map[key] == 'source' ? origArray : destArray;
    for (var i = 0; arr[i].ID != key; i++) ;
    resultArray.push({
        Name: arr[i].Name,
        URL: arr[i].URL,
        ID: arr[i].ID,
        desc: 'missing in ' + map[key]
    });
}

// show result in StackOverflow snippet
document.write(JSON.stringify(resultArray));
Guffa
  • 687,336
  • 108
  • 737
  • 1,005
0
var result = [];

for(var i = 0; i < oa.length; i++) {
    var idx = mIndexOf(oa[i].ID);
    if(idx > -1) {
        oa.splice(i, 1);
        da.splice(idx, 1);
    }
}

for(var i = 0; i < oa.length; i++) {
    var ln = result.length;
    result[ln] = oa[i];
    result[ln].desc = "missing in destination";
}
for(var i = 0; i < da.length; i++) {
    var ln = result.length;
    result[ln] = da[i];
    result[ln].desc = "missing in origin";
}

function mIndexOf(id) {
    for(var i = 0; i < oa.length; i++)
        if(oa[i].ID == id)
            return i;
    return -1;
}

console.log(result);

0: Object
ID: 345
Name: "Double"
URL: "yyy"
desc: "missing in destination"

1: Object
ID: 888
Name: "Double"
URL: "yyy"
desc: "missing in origin"

jsfiddle DEMO

Samurai
  • 3,724
  • 5
  • 27
  • 39
-1

For things like this, you should use lodash. With lodash you can just do this:

var resultArray = _.defaults(destArray, origArray);
Sterling Silver
  • 243
  • 1
  • 13
  • `_.defaults` merges two objects without overwriting keys in `destArray`. It does not solve the asker's problem, in which he wants to compare two objects and find their disjoint set. – Interrobang May 14 '15 at 00:08