I want to be able to get a list of all differences between two JavaScript object graphs, with the property names and values where the deltas occur.
For what it is w
var d = {
FirstName : "John",
LastName : "Doh",
Age : 30,
EMailAddresses : [
"john.doe@gmail.com",
"jd@initials.com"
],
Children : [
{
FirstName : "Sara",
LastName : "Doe",
Age : 2
}, {
FirstName : "Beth",
LastName : "Doe",
Age : 5
}
]
};
var f = {
FirstName : "John",
LastName : "Doe",
Age : 33,
EMailAddresses : [
"john.doe@gmail.com",
"jdoe@hotmail.com"
],
Children : [
{
FirstName : "Sara",
LastName : "Doe",
Age : 3
}, {
FirstName : "Bethany",
LastName : "Doe",
Age : 5
}
]
};
resultobj = []
function comp_obj(t1,t2){
flag = 1;
key1_arr = Object.keys(t1)
key2_arr = Object.keys(t2)
if(key1_arr.length == key2_arr.length){
for(key1 in t1){
ty1 = Object.prototype.toString.call(t1[key1])
ty2 = Object.prototype.toString.call(t2[key1])
if(ty1 == ty2) {
if(ty1 == '[object String]' || ty1 == '[object Number]' ){
if(t2[key1] != t1[key1]){
flag = 0;
break;
}
}else if(ty1 == '[object Array]'){
var result = comp_arr(t1[key1],t2[key1]);
console.log(ty1,ty2)
if(!result)
flag = 0;
}else if(ty1 == '[object Object]'){
var result = comp_obj(t1[key1],t2[key1])
if(!result)
flag = 0;
}
}else{
flag = 0;
break;
}
}
}else{
flag = 0;
}
if(flag)
return true
else
return false;
}
function comp_arr(a,b){
flag = 1;
if(a.length == b.length ){
for(var i=0,l=a.length;i<l;i++){
type1 = Object.prototype.toString.call(a[i])
type2 = Object.prototype.toString.call(b[i])
if(type1 == type2) {
if(type1 == '[object String]' || type1 == '[object Number]' ){
if( a[i] != b[i]){
flag = 0;
break;
}
}else if(type1 == '[object Array]'){
var result = comp_arr(a[i],b[i]);
if(!result)
flag = 0;
}else if(type1 == '[object Object]'){
var result = comp_obj(a[i],b[i])
if(!result)
flag = 0;
}
}else{
flag = 0;
break;
}
}
}else
flag = 0;
if(flag)
return true
else
return false;
}
function create(t,attr,parent_node,innerdata){
var dom = document.createElement(t)
for(key in attr){
dom.setAttribute(key,attr[key])
}
dom.innerHTML = innerdata;
parent_node.appendChild(dom)
return dom;
}
window.onload = function () {
for(key in f){
if(!(key in d))
resultobj.push({'Property_name':key,'f_value':JSON.stringify(f[key]),'d_value':JSON.stringify(d[key])})
type1 = Object.prototype.toString.call(f[key])
type2 = Object.prototype.toString.call(d[key])
if(type1 == type2){
if(type1 == '[object String]' || type1 == '[object Number]' ){
if(f[key] != d[key])
resultobj.push({'Property_name':key,'f_value':JSON.stringify(f[key]),'d_value':JSON.stringify(d[key])})
}else if(type1 == '[object Array]'){
var result = comp_arr(f[key],d[key]);
if(!result)
resultobj.push({'Property_name':key,'f_value':JSON.stringify(f[key]),'d_value':JSON.stringify(d[key])})
}else if(type1 == '[object Object]'){
var result = comp_obj(f[key],d[key])
if(!result)
resultobj.push({'Property_name':key,'f_value':JSON.stringify(f[key]),'d_value':JSON.stringify(d[key])})
}
}else
resultobj.push({'Property_name':key,'f_value':JSON.stringify(f[key]),'d_value':JSON.stringify(d[key])})
}
var tb = document.getElementById('diff');
var s1 = document.getElementById('source1');
var s2 = document.getElementById('source2');
s1.innerHTML = 'Object 1 :'+ JSON.stringify(f)
s2.innerHTML = 'Object 2 :'+JSON.stringify(d)
resultobj.forEach(function(data,i){
tr_dom = create('tr',{},tb,'')
no = create('td',{},tr_dom,i+1)
Object.keys(data).forEach(function(tr){
td_dom = create('td',{},tr_dom,data[tr])
})
})
}
<html>
<body>
<p id="source1"> </p>
<p id="source2"> </p>
<p id="source7"> DIFFERENCE TABLE</p>
<table border=''>
<thead>
<th>S.no</th>
<th>Name Of the Key</th>
<th>Object1 Value</th>
<th>Object2 Value</th>
</thead>
<tbody id="diff">
</tbody>
</table>
</body>
</html>
None of the libraries I found were sufficient so I wrote my own AngularJS factory. It compares the objects in both ways and returns only the difference within the same structure.
/**
* Diff
* Original author: Danny Coulombe
* Creation date: 2016-05-18
*
* Work with objects to find their differences.
*/
controllers.factory('diff', [function() {
var factory = {
/**
* Compare the original object with the modified one and return their differences.
*
* @param original: Object
* @param modified: Object
*
* @return Object
*/
getDifferences: function(original, modified) {
var type = modified.constructor === Array ? [] : {};
var result = angular.copy(type);
var comparisons = [[original, modified, 1], [modified, original, 0]];
comparisons.forEach(function(comparison) {
angular.forEach(comparison[0], function(value, key) {
if(result[key] === undefined) {
if(comparison[1][key] !== undefined && value !== null && comparison[1][key] !== null && [Object, Array].indexOf(comparison[1][key].constructor) !== -1) {
result[key] = factory.getDifferences(value, comparison[1][key]);
}
else if(comparison[1][key] !== value) {
result[key] = comparison[comparison[2]][key];
}
if(angular.equals(type, result[key])
|| result[key] === undefined
|| (
comparison[0][key] !== undefined
&& result[key] !== null
&& comparison[0][key] !== null
&& comparison[0][key].length === comparison[1][key].length
&& result[key].length === 0
)) {
delete result[key];
}
}
});
});
return result;
}
};
return factory;
}]);
I recently wrote a module to do this, because I wasn't satisfied with the numerous diffing modules I found (I listed a bunch of the most popular modules and why they weren't acceptable in the readme of my module). Its called odiff
: https://github.com/Tixit/odiff . Here's an example:
var a = [{a:1,b:2,c:3}, {x:1,y: 2, z:3}, {w:9,q:8,r:7}]
var b = [{a:1,b:2,c:3},{t:4,y:5,u:6},{x:1,y:'3',z:3},{t:9,y:9,u:9},{w:9,q:8,r:7}]
var diffs = odiff(a,b)
/* diffs now contains:
[{type: 'add', path:[], index: 2, vals: [{t:9,y:9,u:9}]},
{type: 'set', path:[1,'y'], val: '3'},
{type: 'add', path:[], index: 1, vals: [{t:4,y:5,u:6}]}
]
*/
There is an objectDiff library which allows you to do that. On its demo page you can see a difference between two javascript objects.
After reviewing the existing answers, I noticed that the https://github.com/flitbit/diff library was not yet listed as a solution.
From my research, this library seems to be the best in terms of active development, contributions and forks for solving the challenge of diffing objects. This is very handy for creating a diff on the server side and passing the client only the changed bits.
you can do'it with filter and indexOf
var first = [ 1, 2, 3, 4, 5 ];
var second = [ 4, 5, 6 ];
var difference = first.filter(x => second.indexOf(x) === -1);
console.log(difference);