Merge 2 JSON Strings, or Object Structures

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • skbach
    New Member
    • Jul 2008
    • 2

    Merge 2 JSON Strings, or Object Structures

    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:

    Code:
    var json1 = { "root": { "Company": {"Name":"CompanyName", "Address":"MainStreet"} } }
    var json2 = { "root": {"AnotherObj": { "Property":"Value"}, "Company" : {"Phone":"604"} }
    
    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.
  • rnd me
    Recognized Expert Contributor
    • Jun 2007
    • 427

    #2
    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.

    Comment

    • skbach
      New Member
      • Jul 2008
      • 2

      #3
      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 appended...is 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.

      Code:
      var firstObj = { "Type":"1", "Company": {"CompanyAddresses":[ {"Address": {"PostalCode":"V6H1S2", "AddressLine1":"3318 Main"}}]} };
                      var secondObj = { "Type":"1", "Company": {"CompanyAddresses":[ {"Address": {"AddressLine2":"#2"}}]} }

      Code:
      for(var i in objA ) {
              var found = new Array();
              for(var j in objB ) {
                  if(i==j) {
                      found.push(j);
                      for(var k in objB[j] ) {
                          objA[i][k] = objB[j][k];
                      }
                  }
              }
              for(var j in objB) {
                  if(found.indexOf(j) == -1) {
                      objA[j] = objB[j];
                  }
              }
          }

      Comment

      • rnd me
        Recognized Expert Contributor
        • Jun 2007
        • 427

        #4
        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:

        Code:
        Object.prototype.merge =  function (ob) {//merges and over-write left side object property with new and like properties in the passed object.
                var o = this;
                var i = 0;
                for (var z in ob) {
                    if (ob.hasOwnProperty(z)) {
                        o[z] = ob[z];
                    }
                }
                return o;
            }
        
        //usage examples:
        var one = { name:"Number One", age: 33, paid: true}
        var two = { age: 44, paid: true }
        var three = { name: "Number Three" }
        
        one.merge(two) // ={name:"Number One", age:44, paid:true}
        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.

        Comment

        Working...