简体   繁体   English

通过递归添加它们的值来合并2个javascript对象

[英]merge 2 javascript objects by recursively adding their values

I want to be able to merge two objects by adding their values together. 我想通过将它们的值一起添加来合并两个对象。

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

I want to obtain : 我想获得:

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

I've tried this but it doesn't 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 ? 有任何想法吗 ?

First, let's define an abstract function that applies a func to a combination of two objects, and then use it together with the summation function. 首先,让我们定义一个抽象函数,它将func应用于两个对象的组合,然后将它与求和函数一起使用。

 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)); 

merge can be also written in a more functional style, like this: merge也可以用更实用的样式编写,如下所示:

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're fine with the first object being changed, you can skip the clone step and just pass x . 如果您对第一个被更改的对象没问题,可以跳过clone步骤并传递x

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;
}

To use as 用作

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

Create a resultArray to avoid complexity with obj1. 创建resultArray以避免使用obj1的复杂性。 Then just add each value in obj1 to the resultArray with the value of obj2 accumulated if the corresponding key in obj2 exists. 然后,如果obj2中存在相应的键,则将obj1中的每个值添加到resultArray中,并将obj2的值累积。

Then add each key in obj2 that was not yet added by the first iteration to the resultArray, so that you don't lose the data from obj2. 然后将第一次迭代中尚未添加的obj2中的每个键添加到resultArray中,这样就不会丢失来自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;
     }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM