0

Here is the example:

I have this jsonA

{ "a":"1", "b":"2", "c":{"a":"1", "b":"2"} }

and this jsonB

{ "b":"2new", "c":{"a":"1new"} }

I want update the first jsonA with the new value in jsonB and, at the end, have this result:

{ "a":"1", "b":"2new", "c":{"a":"1new", "b":"2"} }

manually i could to set every value, like:

jsonA.b = jsonB.b;
jsonA.c.a = jsonB.c.a;

There is a way to do it automatically without check every valule with a forEach?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
mtoninelli
  • 686
  • 1
  • 6
  • 21

2 Answers2

6

Because you hadn't specified the language tag, I went ahead and implemented it in .

Here's the main program:

int main()
{
    auto jsonA = JSON::parse("{ \"a\":\"1\", \"b\":\"2\", \"c\":{\"a\":\"1\", \"b\":\"2\"} }");
    auto jsonB = JSON::parse("{ \"b\":42, \"c\":{\"a\":\"1new\"}, \"q\":[3.14,null] }");

    if (boost::apply_visitor(make_love(), jsonA, jsonB))
        std::cout << "Merged: " << jsonA;
    else
        std::cerr << "Couldn't merge '" << jsonA << "' with '" << jsonB << "'\n";
}

Output:

Merged: {"a":"1","b":42,"c":{"a":"1new","b":"2"},"q":[3.14,null]}

Of course, this just begs the question of how make_love is implemented:

struct make_love : boost::static_visitor<bool>
{
    bool operator()(Object& a, Object const& b) const {
        for(auto el: b.values) 
            recurse(a[el.first], el.second);
        return true;
    }
    template<typename T, typename U> bool operator()(T& a, U const& b)  const 
        { return false; }

  private:
    void recurse(Value& a, Value const& b) const {
        if (!boost::apply_visitor(*this, a, b))
            a = b;
    }
};

Full code in context (JSON.hpp/JSON.cpp): https://github.com/sehe/spirit-v2-json/blob/q17711850/test.cpp

sehe
  • 374,641
  • 47
  • 450
  • 633
  • great, thank you man! i'm writing in javascript. but i think it will be very helpful also for the project i'm doing. really thanks! – mtoninelli Jul 18 '13 at 00:06
  • 1
    Cheers, I just updated the `make_love` implementation to handle heterogenous leaf nodes without a problem and reporting failures. It came in 12 lines shorter, and I changed the demo testcase to show the new feature. – sehe Jul 18 '13 at 00:24
1

I just wrote this:

jsonA = { "a":"1", "b":"2", "c":{"a":"1", "b":"2"} }

jsonB = { "b":"2new", "c":{"a":"1new"} }

for (var j in jsonA) {
    if(jsonB.hasOwnProperty(j)) {
        if (typeof jsonA[j] === 'object') {
            for (var i in jsonA[j]) {
                if(jsonB[j].hasOwnProperty(i)) {
                   jsonA[j][i] = jsonB[j][i];
                }
            }
        } else {
            jsonA[j] = jsonB[j];

        }
    }

}

Check it out here: http://jsfiddle.net/YtgQS/

SharkofMirkwood
  • 11,483
  • 2
  • 17
  • 25
  • 2
    Note that you are processing JavaScript objects, not JSON. OP didn't mention which language they are using. – Felix Kling Jul 17 '13 at 23:33
  • And this seem to work only two levels deep. Maybe recursion can help. – Thilo Jul 17 '13 at 23:34
  • Also, it does not add any new properties that are only in B (but not in A). Of course, that could be part of the spec. – Thilo Jul 17 '13 at 23:35
  • 1
    Hmm yeah. Well I just wanted to give an example, the hope is that the OP could modify it as needed. I dunno, if I had more info I might've produced something different. – SharkofMirkwood Jul 17 '13 at 23:36
  • 2
    As for anyone else else reading, for reference, honestly I'd suggest looking at stackoverflow.com/a/383245/14955 as @Thilo commented on the OP. This was just something I wrote, but making it recursive and looking closer at the second object would be a much better way of doing this. – SharkofMirkwood Jul 17 '13 at 23:40
  • @SharkofMirkwood It's a shame you added the language tag. I was already off do some real C++ chops. I hope you still appreciate my answer as an... _alternative way of doing things_ :D – sehe Jul 18 '13 at 00:03
  • It wasn't me who added the tag :P Nice extensive answer though! +1 for that. – SharkofMirkwood Jul 18 '13 at 00:06