By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
437,605 Members | 2,129 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 437,605 IT Pros & Developers. It's quick & easy.

Merge 2 JSON Strings, or Object Structures

P: 2
I have the following relatively simple requirement:

I have 2 JSON strings, which contains varying nested objects. I need to merge the two strings into one string, maintaining all the hierarchies. I suspect I need some sort of recursive regular expression, but this is outside my area of expertise.

Any help is greatly appreciated.

For example:

Expand|Select|Wrap|Line Numbers
  1. var json1 = { "root": { "Company": {"Name":"CompanyName", "Address":"MainStreet"} } }
  2. var json2 = { "root": {"AnotherObj": { "Property":"Value"}, "Company" : {"Phone":"604"} }
  4. var merged = { "root" : {"Company": {"Name":"CompanyName", "Address":"MainStreet", "Phone":"604"}, "AnotherObj": {"Property":"Value"} } }
So, The fields of the company object from the second string have been appended into company fields of the first string. I would also like to account for arrays.
Jul 18 '08 #1
Share this Question
Share on Google+
3 Replies

rnd me
Expert 100+
P: 427
far easier to eval, merge, then restringify usinf .toSource or .toJSONString() (json.js).

is that how the json has to come, or do you have some control over the way it is constructed? right now, it would be a bit of a bear, but with a few simple changes, they could easily be merged.
Jul 18 '08 #2

P: 2
I have control over the JSON.

I'm willing to either recursively loop through the objects, or use regex to merge the strings and then eval...either way.

But I've spent all week on this damn thing and I can't do it anymore.

I'm almost there, but each solution is not quite good enough.

So, for example in the code below, the first object has an Address object with several properties, and the second object has that same Address object with different properties.

Currently, the properties of the first object are getting overriden, instead of merged.

If the properties are the same in both objects, then they can be overridden (no duplicates), but if they're different, then I'd like them to be this simple ??

The following code "almost" does what I want, but it just overwrites after the first level, so I think it needs recursion.

I'm very open to your string idea at this point.

Expand|Select|Wrap|Line Numbers
  1. var firstObj = { "Type":"1", "Company": {"CompanyAddresses":[ {"Address": {"PostalCode":"V6H1S2", "AddressLine1":"3318 Main"}}]} };
  2.                 var secondObj = { "Type":"1", "Company": {"CompanyAddresses":[ {"Address": {"AddressLine2":"#2"}}]} }

Expand|Select|Wrap|Line Numbers
  1. for(var i in objA ) {
  2.         var found = new Array();
  3.         for(var j in objB ) {
  4.             if(i==j) {
  5.                 found.push(j);
  6.                 for(var k in objB[j] ) {
  7.                     objA[i][k] = objB[j][k];
  8.                 }
  9.             }
  10.         }
  11.         for(var j in objB) {
  12.             if(found.indexOf(j) == -1) {
  13.                 objA[j] = objB[j];
  14.             }
  15.         }
  16.     }
Jul 18 '08 #3

rnd me
Expert 100+
P: 427
the object container really complicates it. if you can turn it into an array, it would be much simpler to use the following code in a loop:

Expand|Select|Wrap|Line Numbers
  1. Object.prototype.merge =  function (ob) {//merges and over-write left side object property with new and like properties in the passed object.
  2.         var o = this;
  3.         var i = 0;
  4.         for (var z in ob) {
  5.             if (ob.hasOwnProperty(z)) {
  6.                 o[z] = ob[z];
  7.             }
  8.         }
  9.         return o;
  10.     }
  12. //usage examples:
  13. var one = { name:"Number One", age: 33, paid: true}
  14. var two = { age: 44, paid: true }
  15. var three = { name: "Number Three" }
  17. one.merge(two) // ={name:"Number One", age:44, paid:true}
  18. one.merge(two).merge(three)//={name:"Number Three", age:44, paid:true}
once youi get into the array, you can build an JSON-like object extracting all the keys you need for a custom match. then you can merge that anon object with your master object, completing the merge.

you can modify the merge proto pretty easily to make a .update (no new keys), or .renew(only new keys) methods as well.

then you just start chaining-up protos, and you are basically done.
if you flatten it to an array, you wont need recursion, or slow, fragile regexps.
Jul 19 '08 #4

Post your reply

Sign in to post your reply or Sign up for a free account.