Search code examples
javascriptcoffeescriptunderscore.js

JavaScript/Coffeescript sum objects


I would love to "add/merge" (not sure how to call that) some objects in this manner:

obj1 = { 
  a: 1,
  b: 1,
  c: 1
}

obj2 = { 
  a: 1,
  b: 1
}

obj1 + obj2 => { a: 2, b: 2, c: 1 }

Is there any way of achieving this? Tried, Object.assign(obj1, obj2) but It will not add properties like I need it to be done (it returns in { a: 1, b: 1, c: 1})


Solution

  • There isn't a built-in way to do it but you can enumerate the properties of one object and add their values to another.

    const a = { a: 1, b: 1, c: 1 };
    const b = { a: 1, b: 1 };
    for(const prop in b) {
      a[prop] = (prop in a ? a[prop] : 0) + b[prop];
    }
    console.log(a);

    The prop in a check is so that we don't end up with NaN by adding undefined to the value in b.

    You could use reduce to combine n number of objects like so:

    const a = { a: 1, b: 1, c: 1 };
    const b = { a: 1, b: 1 };
    const c = { a: 1, c: 1 };
    const result = [a, b, c].reduce((p, c) => {
      for(const prop in c) {
        p[prop] = (prop in p ? p[prop] : 0) + c[prop];
      }
      return p;
    }, {});
    console.log(result);

    You didn't mention how you wanted to deal with properties in the prototype chain. You should know that for...in will enumerate properties in the prototype chain and prop in x will also examine the prototype chain. If your only want to enumerate the objects own properties then you could use Object.entries() to get its own properties or do a hasOwnProperty(...) check within the for...in and in place of the prop in x check. If you don't do any prototypal inheritance with your models then you may not care.