Merge 2 javascript objects by recursively adding their values

I want to combine two objects by adding them together.

> a
{ "a" : 1, "b" : 3, "d": {"da": 1}}
> b
{ "a" : 1, "c" : 34, "d": {"da": 2} }

I want to receive:

> { "a" : 2, "b": 3, "c" : 34, "d": {"da": 3} }

I tried this, but it does not work:

 function MergeRecursive(obj1, obj2) {
   for (var p in obj2) {
     try {
       // Property in destination object set; update its value.
       if ( obj2[p].constructor==Object ) {
         obj1[p] += MergeRecursive(obj1[p], obj2[p]);

       } else {
             obj1[p] = obj2[p];
       }

     } catch(e) {
       // Property in destination object not set; create it and set its value.
             obj1[p] = obj2[p];
     }
   }
   return obj1;
 }

Any ideas?

+4
source share
3 answers

First we define an abstract function that applies func to a combination of two objects, and then uses it together with the sum function.

function merge(x, y, fn) {
    var result = {};

    Object.keys(x).forEach(function(k) {
        result[k] = x[k];
    });

    Object.keys(y).forEach(function(k) {
        result[k] = k in x ? fn(x[k], y[k]) : y[k];
    });

    return result;
}

function add(p, q) {
    if(typeof p === 'object' && typeof q === 'object') {
        return merge(p, q, add);
    }
    return p + q;
}

a = { "a" : 1, "b" : 3, "d": {"da": 1}};
b = { "a" : 1, "c" : 34, "d": {"da": 2}};

sum = merge(a, b, add)
document.write('<pre>'+JSON.stringify(sum,0,3));
Run codeHide result

merge can also be written in a more functional style, for example:

function clone(x) {
    return Object.keys(x).reduce(function(res, k) {
        res[k] = x[k];
        return res;
    }, {});
}

function merge(x, y, fn) {
    return Object.keys(y).reduce(function(res, k) {
        res[k] = k in x ? fn(x[k], y[k]) : y[k];
        return res;
    }, clone(x));
}

If you are ok with the first object changed, you can skip the step cloneand just go through x.

+3
source

My attempt

function MergeRecursive(obj1, obj2) {
    var k = Object.keys(obj1), i = 0;
    for (var p in obj2) {
        if(typeof obj1[p] == 'object' && typeof obj2[p] == 'object')
            obj2[p] = MergeRecursive(obj1[p],obj2[p]);
        else if(obj1[p] != null)
            obj2[p] += obj1[p];
        else
            obj2[k[i]] = obj1[k[i]];
        i++;
    }
    return obj2;
}

Use as

MergeRecursive({ "a" : 1, "b" : 3, "d": {"da": 1}},{ "a" : 1, "c" : 34, "d": {"da": 2} })
0
source

resultArray, obj1. obj1 resultArray obj2, obj2.

Then add each key in obj2 that has not yet been added by the first iteration to resultArray so that you do not lose data from obj2.

   function MergeRecursive(obj1, obj2) {
       resultArray = [];
       for (var key in obj1) {
           if ( typeof obj1[key] === 'object') {
               resultArray[key] = MergeRecursive(obj1[p], obj2[p]);
           } else {
               resultArray[key] = obj1[key] + obj2[p] ?? 0;
           }
       }
       for (var key in obj2) {
           if (key in resultArray){
               continue;
           }
           resultArray[key] = obj2[key];
       }
       return resultArray;
     }
0
source

Source: https://habr.com/ru/post/1626506/


All Articles