【问题标题】:Is there an easy way to merge objects and sum their int properties instead of overriding in javascript es2018? [duplicate]有没有一种简单的方法来合并对象并将它们的 int 属性求和,而不是在 javascript es2018 中覆盖? [复制]
【发布时间】:2026-02-12 00:05:01
【问题描述】:

好吧,这就是我的想法。

我有两个示例对象

let obj1 = { x: 60 };

let obj2 = { x: 9 };

我想合并这些对象,使它们的整数属性也可以组合,而不是相互覆盖,所以最终结果将是

let obj3 = { x: 69 };

所以我研究了 Object.assign,但是如果其他对象具有同名的属性,则此函数仅以有利于第一个对象上的属性的方式合并属性,并且不会对整数属性求和.

当然,我可以只创建一个函数来循环每个对象的属性并创建一个具有总和属性的新对象,但这会更长,我想知道是否已经有一个函数可以轻松完成Object.assign 的作用方式。

谢谢。

【问题讨论】:

  • 没有内置工具可以做到这一点。
  • 这不是合并的定义,你看的更多的是求和
  • @CharybdeBE 我知道,这就是我最终在问题中所说的。那么,最有效的方法是什么?或者除了循环和循环之外没有其他方法。
  • 是的,你不会绕过循环(注意Object.assign 并不比循环更有效,它只是语法糖)。当然,您可以编写一些符合您需要的辅助函数,同时具有相同的易用性。

标签: javascript ecmascript-6 ecmascript-2016


【解决方案1】:

如果你想使用Lodash 库,你可以使用mergeWith 方法。

let obj1 = { x: 60, b: "foo", c: {y: 3, x: 'bar'} };
let obj2 = { x: 9, a: 'bar', c: {y: 4} };

const sum = _.mergeWith(obj1, obj2, (a, b) => {
  if (_.every([a, b], _.isNumber)) return a + b;
})

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

【讨论】:

【解决方案2】:

像这样?

let obj1 = { x: 60 };
let obj2 = { x: 9 };

let obj3 = [obj1, obj2].reduce((s,a)=>{return {x: s.x+a.x}}, {x:0});
 
console.log(obj3);

// or more shortener:

obj3 = {x:[obj1, obj2].reduce((s,a)=> s + a.x,0)};

console.log(obj3);

// for arbitrary properties, not just x:

keys = Object.keys(obj1),
obj3 = [obj1, obj2].reduce(function (r, o) {
    keys.forEach(function (k) {
        r[k] += o[k];
    });
    return r;
}, keys.reduce(function (r, k) {
    r[k] = 0;
    return r;
}, Object.create(null)));

console.log(obj3);

【讨论】:

  • 我猜 OP 正在寻求对任意属性执行此操作,而不仅仅是 x
  • 这正确回答了这个问题,但没有像 Nenad Vracar 的回答那样走得更远。这不适用于 {foo: 10, bar: 'baz'}{foo: {bar: 10}} 等对象
  • 贝尔吉,好的。我修好了。
  • 我一开始没有发表评论,因为您的代码仅用于一个值,并且任意属性编辑后的代码并不是真正的答案,因为我正在寻找一种简单、快捷的方法。否则我可以自己制作这个功能......但感谢您的努力。
【解决方案3】:

您可以通过获取任意数量的对象来减少对象,并通过尊重嵌套对象来减少键/值对。

const
    add = (...a) => a                         // take all parameters
        .map(Object.entries)                  // get entries
        .reduce((a, b) => [...a, ...b], [])   // flat entries
        .reduce((o, [k, v]) => {
            o[k] = v && typeof v === 'object' // assign if object
                ? add(o[k] || {}, v)          //   result of recursive call
                : (o[k] || 0) + v;            //   or sum the value
            return o;
        }, {});

let obj1 = { x: 60, y: { z: 3 } },
    obj2 = { x: 9, y: { z: 1, a: 32 } },
    obj3 = { y: { a: 10 } },
    result = add(obj1, obj2, obj3);

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

【讨论】:

  • 一如既往的好答案,但我认为人们会喜欢 cmets 和/或更明确的变量名称