merge JSON structures

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • hobosalesman@gmail.com

    merge JSON structures

    Is there a function or library somewhere that merges 2 JSON data
    structures? For instance this:

    { "one": [1,3] }

    plus

    { "one": [2] }

    equals

    { "one": [1,2,3] }

  • webEater

    #2
    Re: merge JSON structures



    On 13 Nov., 05:43, hobosales...@gm ail.com wrote:
    Is there a function or library somewhere that merges 2 JSON data
    structures? For instance this:
    >
    { "one": [1,3] }
    >
    plus
    >
    { "one": [2] }
    >
    equals
    >
    { "one": [1,2,3] }
    This is a very special case. In prototype library you find
    Object.extend() , but it overwrites same keys. You need a special
    funcion that concats Arrays key for key (if the key holds an array),
    e.g.

    Object.plus = function(obj1, obj2) {
    var res = {};
    // "copy" obj1 keys to new object res
    Object.extend(r es, obj1);
    // now overwrite obj1 keys in res by contents of obj2
    Object.extend(r es, obj2);
    // now consider overwritten obj 1 keys one by one, like in example -
    only arrays
    for(var key in obj1) {
    if (obj1[key] instanceof Array)
    // concatenate Arrays, don't sort them like in your example
    res[key] = obj1[key].concat(res[key]);
    }
    }

    I hope I could help you, for Object.extend look in


    Andi

    Comment

    • webEater

      #3
      Re: merge JSON structures

      And return the result:

      Object.plus = function(obj1, obj2) {
      ...
      return res;
      }

      Comment

      • RobG

        #4
        Re: merge JSON structures

        hobosalesman@gm ail.com wrote:
        Is there a function or library somewhere that merges 2 JSON data
        structures? For instance this:
        >
        { "one": [1,3] }
        >
        plus
        >
        { "one": [2] }
        >
        equals
        >
        { "one": [1,2,3] }
        If you are specifically after the above structure, then the following
        should do the trick:

        <script type="text/javascript" src="json.js"></script>
        <script type="text/javascript">

        var jsonStr1 = '{ "one": [1,3] }';
        var jsonStr2 = '{ "one": [2],'
        + ' "two": [1]}';

        function jsonAdd(str1, str2){
        var obj1 = eval('(' + str1 + ')');
        var obj2 = eval('(' + str2 + ')');
        for (var prop in obj2){
        if (obj2[prop] instanceof Array){
        if (prop in obj1){
        obj1[prop] = obj1[prop].concat(obj2[prop]);
        } else {
        obj1[prop] = obj2[prop].concat();
        }
        }
        }
        return obj1.toJSONStri ng();
        }

        alert( jsonAdd(jsonStr 1, jsonStr2) );

        </script>

        where json.js can be found at: <URL: http://www.json.org/json.js >. If
        you don't want to extend the Array prototype (and therefore could
        remove the instanceof Array test), there is a functionalised version
        that is no longer available from json.org - it has been posted here:
        <URL:
        http://groups.google.com.au/group/ru...43fb9e0b2f5a3d
        >

        --
        Rob

        Comment

        • hobosalesman@gmail.com

          #5
          Re: merge JSON structures

          webEater wrote:
          This is a very special case. In prototype library you find
          Object.extend() , but it overwrites same keys. You need a special
          funcion that concats Arrays key for key (if the key holds an array),
          It gets more complicated because { "this":"tha t" } is an object with no
          concat method. So from what I can tell I need to write my own function
          that looks at typeof and the constructor property to tell if I have an
          array, object, or something else, and either concat, straight assign,
          or loop through object properties and assign. Yuck, oh well.

          I'm sure someone has done this before, I've never been into javascript,
          there isn't anything like CPAN or PEAR for JS is there? All these "free
          DHTML scripts!" web sites sure don't cut it.

          HS

          Comment

          • hobosalesman@gmail.com

            #6
            Re: merge JSON structures

            RobG wrote:
            If you are specifically after the above structure
            Nope, I'm after a big complicated structure that'll probably get bigger
            and more complicated later. But thanks!
            where json.js can be found at: <URL: http://www.json.org/json.js >. If
            Thanks for that link.

            HS

            Comment

            • RobG

              #7
              Re: merge JSON structures


              hobosalesman@gm ail.com wrote:
              RobG wrote:
              If you are specifically after the above structure
              >
              Nope, I'm after a big complicated structure that'll probably get bigger
              and more complicated later. But thanks!
              Presumably you are only going to "join" properties with the same name
              and type. The concept of your "join" only makes sense for Array or
              String objects, I've shown an Array concat, adding a String concat
              would be trivial.

              What will you do with properties that are Boolean or Number (guessing
              that Undefined and Null are irrelevant)?


              --
              Rob

              Comment

              • hobosalesman@gmail.com

                #8
                Re: merge JSON structures

                RobG wrote:
                Presumably you are only going to "join" properties with the same name
                and type. The concept of your "join" only makes sense for Array or
                String objects, I've shown an Array concat, adding a String concat
                would be trivial.
                Well I've kicked this idea around my head for the last day or two, and
                I think it's more complex than it seems at first glance. I have a
                server generated config structure that I want to be merged with a
                hardcoded default JS structure, but I don't want it to obliterate
                nested config variables just because they weren't defined on the
                server.

                I'll call this function mergeJSON(arg1, arg2), take one structure and
                copy it into another, overwriting values that exist, but making sure
                not to lose any data unless necessary. For instance:

                ret = mergeJSON( [ {"one": 1} ], [ {"one": 2} ] )

                If we just looked at each argument's constructor, saw an array, and did
                arg1.concat(arg 2), we'd get:

                [ {"one": 1}, {"one": 2} ]

                But I want to look at ret[0].one and find the value defined in arg1, or
                if it doesn't exist the value defined in arg2. In other words, I want
                this:

                [ {"one": 1} ]

                So it's not as simple as it seems on the surface I think. It has to
                recurse through each level of the hierarchy, working down to "leaf
                nodes", merging everything manually rather than using concat.
                What will you do with properties that are Boolean or Number (guessing
                Overwrite arg2 if they exist in both.
                that Undefined and Null are irrelevant)?
                If undefined don't overwrite any data, but null is defined, so
                overwrite just like a bool, number, string. I could concat strings but
                it doesn't work in the context I need it. It would be trivial to concat
                strings when a flag is passed though.

                I'll post what I come up with if anyone's interested, in the meantime I
                welcome feedback.

                HS

                Comment

                • hobosalesman@gmail.com

                  #9
                  Re: merge JSON structures

                  Stupid javascript doesn't pass by reference and keeps saying "too much
                  recursion". I want a real language. Maybe I can send it back to the
                  server with ajax and use perl. I have no idea how to get around the
                  "too much recursion", it says that even when only recursing once with a
                  single element array. Without recursion it becomes ugly and limited.
                  What's this no recursion thing? Surely javascript allows recursive
                  functions?

                  HS

                  Comment

                  • Matt Kruse

                    #10
                    Re: merge JSON structures

                    hobosalesman@gm ail.com wrote:
                    Stupid javascript doesn't pass by reference
                    Sure it does, except for primitives.
                    and keeps saying "too much
                    recursion".
                    Then you have probably written bad code ;)
                    I want a real language.
                    s/I want a real language/I want a language that acts how I expect it to, not
                    how it's defined/
                    I have no idea how to get around the
                    "too much recursion", it says that even when only recursing once with
                    a single element array.
                    Then something is wrong.

                    It seems that you want some behavior that "makes sense", but you don't
                    really know what that is. Merging of data structures isn't as simple as you
                    might think.

                    First, write down requirements. How _exactly_ do you want the merge to
                    behave? When merging objects with common properties, which should get
                    priority? Should non-null values always overwrite null values? How should
                    arrays be treated? What about cases like
                    {x:1} and {x:[1]} ? What about {x:[1,2]} and {x:[2,1]} ?

                    Before you can write code, you need to clearly understand what you want. At
                    that point, people here can help you in tweaking the code you create.

                    --
                    Matt Kruse




                    Comment

                    • Richard Cornford

                      #11
                      Re: merge JSON structures

                      Matt Kruse wrote:
                      hobosalesman@gm ail.com wrote:
                      Stupid javascript doesn't pass by reference
                      >
                      Sure it does, except for primitives.
                      >
                      and keeps saying "too much
                      recursion".
                      >
                      Then you have probably written bad code ;)
                      <snip>

                      Erroneous code at minimum. As I recall (and it was a while ago now)
                      testing how much recursion prompted the "too much recursion" warning
                      came up with a figure of around 10,000 recursive calls.

                      Richard.

                      Comment

                      • Randy Webb

                        #12
                        Re: merge JSON structures

                        hobosalesman@gm ail.com said the following on 11/14/2006 5:22 AM:
                        Stupid javascript doesn't pass by reference and keeps saying "too much
                        recursion". I want a real language. Maybe I can send it back to the
                        server with ajax and use perl.
                        And then you have to deal with "Stupid javascript" to be able to use
                        ajax to send it to the server. And if recursion is giving you a
                        headache, I want to be your supplier of headache medicine when you get
                        to the XMLHTTPRequest Object.



                        --
                        Randy
                        Chance Favors The Prepared Mind
                        comp.lang.javas cript FAQ - http://jibbering.com/faq
                        Javascript Best Practices - http://www.JavascriptToolbox.com/bestpractices/

                        Comment

                        • hobosalesman@gmail.com

                          #13
                          Re: merge JSON structures

                          Matt Kruse wrote:
                          hobosalesman@gm ail.com wrote:
                          Stupid javascript doesn't pass by reference
                          >
                          Sure it does, except for primitives.
                          I thought I would have to test for type to find out if I'm passing a
                          reference or not, something that javascript seems to suck at, but I
                          don't think I do.
                          s/I want a real language/I want a language that acts how I expect it to, not
                          how it's defined/
                          Yeah, basically. Another translation would be "Boo hoo I'm not as
                          comfortable writing JS as with other languages I've used 1000 times
                          more often...".
                          and keeps saying "too much
                          recursion".
                          >
                          Then you have probably written bad code ;)
                          I think so. It was late and I don't even remember what I wrote, but I
                          don't have that problem now.
                          First, write down requirements. How _exactly_ do you want the merge to
                          behave? When merging objects with common properties, which should get
                          priority? Should non-null values always overwrite null values? How should
                          arrays be treated? What about cases like
                          {x:1} and {x:[1]} ? What about {x:[1,2]} and {x:[2,1]} ?
                          >
                          Before you can write code, you need to clearly understand what you want. At
                          that point, people here can help you in tweaking the code you create.
                          I have my requirements very clear in my head, I don't think I'm very
                          good at communicating them on usenet though. I think I have what I want
                          here (I hope line wraps don't ruin this, please point out the best way
                          to post code if I screwed up):

                          function merge_json(merg er, mergee) {
                          if (merger.constru ctor.toString() .indexOf("Array ") == -1 &&
                          merger.construc tor.toString(). indexOf("Object ") == -1) {
                          //must have been passed non-JSON
                          return false;
                          }
                          for (i in merger) {
                          if (mergee[i]) {
                          if ((merger[i].constructor.to String().indexO f("Array") == -1 &&
                          merger[i].constructor.to String().indexO f("Object") == -1) ||
                          (mergee[i].constructor.to String().indexO f("Array") == -1 &&
                          mergee[i].constructor.to String().indexO f("Object") == -1)) {
                          //one or the other isn't an array/object
                          mergee[i] = merger[i];
                          } else {
                          merge_json(merg er[i], mergee[i]);
                          }
                          } else {
                          mergee[i] = merger[i];
                          }
                          }
                          return true;
                          }

                          It seems to work, the super ugly if statements notwithstanding .

                          HS

                          Comment

                          • hobosalesman@gmail.com

                            #14
                            Re: merge JSON structures

                            Randy Webb wrote:
                            And then you have to deal with "Stupid javascript" to be able to use
                            ajax to send it to the server. And if recursion is giving you a
                            I was kidding, but wouldn't it be nice to run perl in the browser?
                            Unless you're a user that cares about "security" or things like that.

                            HS

                            Comment

                            • Matt Kruse

                              #15
                              Re: merge JSON structures

                              hobosalesman@gm ail.com wrote:
                              >s/I want a real language/I want a language that acts how I expect it
                              >to, not how it's defined/
                              Yeah, basically. Another translation would be "Boo hoo I'm not as
                              comfortable writing JS as with other languages I've used 1000 times
                              more often...".
                              Indeed, javascript has the ability to frustrate and confuse new users. But
                              it's not as bad as VBScript! (IMO).

                              I didn't check your code functionality or run any tests with it, but I
                              thought I would share a few comments:
                              if (merger.constru ctor.toString() .indexOf("Array ") == -1 &&
                              merger.construc tor.toString(). indexOf("Object ") == -1) {
                              This is not robust, is it? What if I pass in an instance of Car, which is an
                              Object?
                              if (mergee[i]) {
                              if mergee[i] has a value of false or 0, this will be false and it won't be
                              evaluated.
                              Instead you want
                              if (typeof mergee[i]!="undefined" ) {

                              --
                              Matt Kruse




                              Comment

                              Working...