如何从具有相同定义的另一个对象向对象 属性 添加值 In JavaScript

How to add values to an object property from another object having the same definition In JavaScript

我有一个类似于下面的对象:

var obj1 = {
  fparams: {
    keys: ['a', 'b'],
    pairs: {
      'p': 'qwert'
    }
  },
  qparams: {
    'x': 'xyz'
  }
}

另一个是:

var obj2 = {
  fparams: {
    keys: ['c', 'd'],
    pairs: {
      'q': 'yuiop'
    }
  },
  qparams: {
    'z': 'zyx'
  }
}

如何将 obj2 对象的属性添加到 obj1

因为我在 Angular 工作,我尝试使用 angular.merge(obj1,obj2) 但它不会合并键数组,而是用 obj2 中的键值覆盖它,其余的不过属性会合并。

这就是我最终想要的:

var obj2 = {
  fparams: {
    keys: ['a', 'b', 'c', 'd'],
    pairs: {
      'p': 'qwert',
      'q': 'yuiop'
    }
  },
  qparams: {
    'x': 'xyz',
    'y': 'zyx'
  }
}

此外,我使用的 angular 版本是 angular 1.5.8

编辑:最终使用了 lodash ,因为它使用起来更容易,而且还有很多我以前不知道的功能。

您是否考虑过使用 Lodash? It has a merge 方法来做到这一点。

使用 lodash,您可以使用 mergeWith 并创建所需的结果,因此当值是数组时,您需要连接值。

var obj1 = {"fparams":{"keys":["a","b"],"pairs":{"p":"qwert"}},"qparams":{"x":"xyz"}}
var obj2 = {"fparams":{"keys":["c","d"],"pairs":{"q":"yuiop"}},"qparams":{"z":"zyx"}}

var result = _.mergeWith(obj1, obj2, function(a, b) {
  if(_.isArray(a)) return a.concat(b)
})

console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

这是我使用递归进行深度合并的尝试,不确定它是否适用于所有数据结构。

var obj1 = {"fparams":{"keys":["a","b"],"pairs":{"p":"qwert"}},"qparams":{"x":"xyz"}}
var obj2 = {"fparams":{"keys":["c","d"],"pairs":{"q":"yuiop"}},"qparams":{"z":"zyx"}}

function merge(o1, o2) {
  var result = {}
  for (var i in o1) {
    for (var j in o2) {
      if (i == j && typeof o1[i] == 'object' && typeof o2[j] == 'object') {
        if (Array.isArray(o1[i]) || Array.isArray(o2[j])) {
          result[i] = Array.isArray(o1[i]) ? o1[i].concat(o2[j]) : o2[j].concat(o1[i])
        } else {
          result[i] = Object.assign(result[i] || {}, merge(o1[i], o2[j]))
        }
      }
      if (typeof o1[i] != 'object' || typeof o2[j] != 'object') {
        result[i] = o1[i]
        result[j] = o2[j]
      }

    }
  }
  return result;
}

console.log(JSON.stringify(merge(obj1, obj2), 0, 4))

试试这个功能,我已经尝试覆盖大部分场景,尽管它可能不如其他可用的库

var merge = function(obj1, obj2) {

  for (var key in obj2) {
    if (obj2.hasOwnProperty(key)) {
       if (obj1[key] == null) {
           obj1[key] = obj2[key];
       } else if (obj1[key] instanceof Array) {
           if (obj2[key] instanceof Array) {
               for (var i =0; i < obj2[key].length; i++){
                   if (obj1[key].indexOf(obj2[key]) === -1) {
                       obj1[key].push(obj2[key][i]);
                   }
               }
           }
       } else if (obj1[key] instanceof Object && obj2[key] instanceof Object && obj1[key].constructor == Object && obj2[key] == Object) {
           merge(obj1[key], obj2[key]);
       }
    }
  }
}

您可以如下使用

merge(obj1, obj2);

我想简单地用纯 JS 和递归函数的帮助 mergeObjects 你可以做如下;

function mergeObjects(o1,o2){
  return Object.keys(o1)
               .reduce(function(r,k){
                         o1[k] = Array.isArray(o1[k]) ? o1[k].concat(o2[k])
                                                      : typeof o1[k] === "object" ? mergeObjects(o1[k],o2[k])
                                                                                  : (r = Object.assign({},o1,o2),o1[k]);
                         return r;
                       }, o1);
}

var objs = [{
             fparams: {
                       keys : ['a', 'b'],
                       pairs: {
                               'p': 'qwert'
                              }
                      },
             qparams: {
                       'x': 'xyz'
                      }
            },
            {
             fparams: {
                       keys : ['c', 'd'],
                       pairs: {
                               'q': 'yuiop'
                              }
                       },
             qparams: {
                       'z': 'zyx'
                      }
            }],
  result = objs.reduce(mergeObjects);
console.log(JSON.stringify(result,null,2));