2

I want to generate an object from two given objects A and B with only the values from B that differ from A. We can assume that the all fields exist in both A and B.

Example: Given the following two objects:

A

{
    "firstName": "John",
    "lastName": "Doe",
    "nickname": "Johnny",
    "location": {
        "latitude": 1.0,
        "longitude": 1.0
    },
    "email": "john.doe@company.com"
}

B

{
    "firstName": "John",
    "lastName": "Doe",
    "nickname": "John-Boy",
    "location": {
        "latitude": 1.0,
        "longitude": 2.0
    },
    "email": "john.doe@company.com"
}

As nickname and location have changed, I want the result to be:

{
    "nickname": "John-Boy",
    "location": {
        "latitude": 1.0,
        "longitude": 2.0
    }
}

Note that I want the full location object and not just the changed longitude

What would be a good way of achieving this?

Gustav Karlsson
  • 1,151
  • 9
  • 25
  • 1
    See: [***How can I get a list of the differences between two JavaScript object graphs?***](http://stackoverflow.com/questions/264430/how-can-i-get-a-list-of-the-differences-between-two-javascript-object-graphs) and [***Generic deep diff between two objects***](http://stackoverflow.com/questions/8572826/generic-deep-diff-between-two-objects). Please search the site before posting. – Mr. Polywhirl Jan 12 '15 at 11:29
  • 1. I did. For about 15 minutes. 2. Please read my question before drawing conclusions. I don't want a diff. I want a subset of B. Essentially B minus the common values of A and B. Maybe I need to clarify it further? – Gustav Karlsson Jan 12 '15 at 12:09

2 Answers2

1

var array1 = {
    "firstName": "John",
    "lastName": "Doe",
    "nickname": "Johnny",
    "location": {
        "latitude": 1.0,
        "longitude": 1.0
    },
    "email": "john.doe@company.com"
}

var array2 = {
    "firstName": "John",
    "lastName": "Doe",
    "nickname": "John-Boy",
    "location": {
        "latitude": 1.0,
        "longitude": 2.0
    },
    "email": "john.doe@company.com"
}

var currentString;
  var resultObject = {};
 function loopOverObject(sourceObj, targetObj,innerObjName) {
  for (var key in sourceObj) {
   currentString = null;
   if (sourceObj.hasOwnProperty(key)) {
    
    if (typeof sourceObj[key] === "object") {
     loopOverObject(sourceObj[key],targetObj,key);
     break;
    }
    else {
     if (sourceObj[key] !== targetObj[key]) {
      if (innerObjName) {
       if (resultObject[innerObjName]) {
        resultObject[innerObjName][key] = sourceObj[key];
       }
       else {
        resultObject[innerObjName] = JSON.parse('{"'+key+'": '+sourceObj[key]+'}');
       }
      }
      else {
       currentString = sourceObj[key];
      }
     }
    }
    if (currentString) {
     resultObject[key]=currentString;
    }
   }
  }
  return resultObject;
 };
 var result = loopOverObject(array2,array1);
 
var resultDiv = document.getElementById("result")
resultDiv.innerHTML = JSON.stringify(result);
<div id="result"></div>
Yonatan Ayalon
  • 1,959
  • 18
  • 19
0

You could use a differencing module like odiff by getting the list of differences and using them to build a new object appropriately:

var diff = odiff(A,B)
var result= {}
for(var n=0; n<diff.length; n++) {
  var key = diff.path[0] // the top-level key
  result[key] = B[key]
} 

Then you got the result I think you want - that is if you only care about getting the top-level fields that have changed.

B T
  • 57,525
  • 34
  • 189
  • 207