JSON merging
Today Jakob Kruse and I devised a simple javascript function to merge two JSON object structures. Say for instance you have two JSON structures, json1 and json2. The object json1 holds an original set of data, whereas json2 holds updated and added values/objects to json1 and you need to programatically merge the two.
Updated: I have now created a JSON diff method also. Check it out.
Updated: The code has been updated on the 14th of January 2008 to allow merging cyclic structures without requiring an infinite amount of CPU cycles… And here I thought that was a reasonable demand on system ressources. This update requires the Array.indexOf method from the prototype framework.
Well, here you go (JSLint even likes it!):
-
var jsonDataHandler = {
-
merge: function(j1, j2) {
-
if (typeof this.merging === “undefined” || this.merging === 0) {
-
this.cyclicCheck = [];
-
this.merging = 0;
-
}
-
this.merging += 1;
-
if (typeof j1 === “undefined”) {
-
j1 = {};
-
}
-
if (typeof j2 === “undefined”) {
-
j2 = {};
-
}
-
if (typeof this.cyclicCheck === “undefined”) {
-
this.cyclicCheck = [];
-
}
-
var key;
-
for (key in j2) {
-
if (typeof j1[key] === “undefined”) {
-
j1[key] = j2[key];
-
}
-
else {
-
if (typeof j2[key] === “object”) {
-
if (this.cyclicCheck.indexOf(j1[key]) >= 0) {
-
break;
-
}
-
this.merge(j1[key], j2[key]);
-
this.cyclicCheck.push(j1[key]);
-
}
-
else {
-
j1[key] = j2[key];
-
}
-
}
-
}
-
this.merging -= 1;
-
}
-
};
If you run jsonDataHandler.merge on these JSON objects - note the added cyclic references:
-
var json1 = {
-
foo: 42,
-
obj: {
-
hello: “world”,
-
earth: {
-
type: “planet”
-
}
-
},
-
bar: 41,
-
child: {
-
parent: null
-
}
-
};
-
json1.child.parent = json1;
-
var json2 = {
-
foo: 43,
-
obj: {
-
earth: {
-
type: “habitable planet”,
-
classification: “mostly harmless”
-
}
-
},
-
newObj: {
-
very: “nice”
-
},
-
worked: true,
-
children: {
-
parents: null
-
}
-
};
-
json2.children.parents = json2;
you end up with the following value in the json1 object (which is nice):
-
jsonDataHandler.merge(json1, json2);
-
-
/*
-
The value of json1 is now:
-
{
-
foo: 43,
-
obj: {
-
hello: "world",
-
earth: {
-
type: "habitable planet",
-
classification: "mostly harmless"
-
}
-
},
-
bar: 41,
-
child: {
-
parent: json1
-
},
-
newObj: {
-
very: "nice"
-
},
-
worked: true,
-
children: {
-
parents: json1
-
}
-
}
-
*/
A demonstration of the merge function in action on cyclic structures can be found here.
Work still to be done:
Schema support would be neat as all values from json2 are currently copied into json1 without any structural integrity checking being carried out.
Also, a jsonDiff method should be made - which I’ll most likely do when the need arise. It’s done! See link at the top of this article.
And oh, erhm… Don’t use jsonMerge on cyclic structures just yet, it’s currently not supported. It is supported now, enjoy.

