2

Write a function called mergeCounters which accepts two objects where all of the values are numbers and returns a new object with the total of both objects. The order of your returned object does not matter, as long as it contains the correct keys and values!

function mergeCounters (object1, object2) {
  var myObj = {};
  for (key in obj1) {
    for (key2 in obj2) {
      var val = myObj[key + key2];
    }
  }
  return myObj;
}

var obj1 = {a: 1, b:2, c:3};
var obj2 = {a: 3, b:6, c:7};
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = {a: 1, c:3, d:5};
var obj4 = {a: 3, b:6, c:7, z:20};
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
Mark Rubio
  • 29
  • 4
  • 2
    What is `var val = myObj[key + key2];` supposed to do? `key` and `key2` are strings. And why `var val = ...`? – Andreas Mar 03 '21 at 09:12

5 Answers5

4

You don't need a nested loop here since you can use the key to index/access the values from both objects. Since object1 may have more properties than object2 and vice versa, you can first merge all object properties from both object1 and object2 into a merged object using the spread syntax .... Once you have a merged object, you can iterate the keys of the object using for...in, and grab the key from both object1 and object2 to add to the new resulting object. One object may not have the other key, so you can default the value to 0 using || 0 if it doesn't exist.

See example below:

function mergeCounters (object1, object2) {
  const merged = {...object1, ...object2};
  const result = {};
  for(const key in merged) {
    result[key] = (object1[key] || 0) + (object2[key] || 0);
  }
  return result;
}

var obj1 = {a: 1, b:2, c:3};
var obj2 = {a: 3, b:6, c:7};
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = {a: 1, c:3, d:5};
var obj4 = {a: 3, b:6, c:7, z:20};
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
Nick Parsons
  • 45,728
  • 6
  • 46
  • 64
2

This is fairly easy to achieve, the process goes as follows.

  • copy the values of object1 to myObj
  • iterate all of object2, if the key is already present add it, otherwise set it

function mergeCounters (object1, object2) {
   const myObj = { ...object1 };
   for(var key in object2) {
      myObj[key] = (myObj[key] || 0) + object2[key]
   }
   return myObj;
}

var obj1 = {a: 1, b:2, c:3};
var obj2 = {a: 3, b:6, c:7};
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = {a: 1, c:3, d:5};
var obj4 = {a: 3, b:6, c:7, z:20};
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
Jamiec
  • 133,658
  • 13
  • 134
  • 193
2

Reduce version of Nick Parsons' solution

function mergeCounters (object1, object2) {
  return Object.keys({...object1, ...object2}) // collect all keys of both objects
    .reduce((acc, key) => {
      acc[key] = (object1[key] || 0) + (object2[key] || 0); // add the object values together if they exist
      return acc;
    },{})
}

var obj1 = {a: 1, b:2, c:3};
var obj2 = {a: 3, b:6, c:7};
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = {a: 1, c:3, d:5};
var obj4 = {a: 3, b:6, c:7, z:20};
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
mplungjan
  • 169,008
  • 28
  • 173
  • 236
1

Here is another way, for older browsers, that gives the expected results:

function mergeCounters(o1, o2, firstSum) {
  let sum = firstSum || {};
  for (let prop in o1) {
    sum[prop] = sum[prop] === undefined ?
      o1[prop] || 0 + o2[prop] || 0 :
      sum[prop] += o1[prop] || o2[prop];
  }
  if (!firstSum) {
    mergeCounters(o2, o1, sum);
  }
  return sum;
};
var obj1 = {a: 1, b:2, c:3};
var obj2 = {a: 3, b:6, c:7};
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = {a: 1, c:3, d:5};
var obj4 = {a: 3, b:6, c:7, z:20};
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
mplungjan
  • 169,008
  • 28
  • 173
  • 236
Mic
  • 24,812
  • 9
  • 57
  • 70
0

Object.entries(), Array.prototype.concat() and Array.prototype.reduce() can help here

  1. Object.entries(): get all properties and their values
  2. Array.prototype.concat(): combine the properties of both objects
  3. Array.prototype.reduce(): add the properties into one new object and combine the value of properties with the same name

function mergeCounters(objectA, objectB) {
  const entriesA = Object.entries(objectA);
  const entriesB = Object.entries(objectB);

  return entriesA.concat(entriesB)
    .reduce((result, current) => {
      const key = current[0];
      const value = current[1];

      if (typeof result[key] !== "undefined") {
        result[key] = result[key] + value;
      } else {
        result[key] = value;
      }

      return result
    }, {});
}

var obj1 = { a: 1, b: 2, c: 3 };
var obj2 = { a: 3, b: 6, c: 7 };
console.log(mergeCounters(obj1, obj2)); // {a:4, b:8, c:10}

var obj3 = { a: 1, c: 3, d: 5 };
var obj4 = { a: 3, b: 6, c: 7, z: 20 };
console.log(mergeCounters(obj3, obj4)); // {a:4, b:6, c:10, d:5, z:20}
Andreas
  • 21,535
  • 7
  • 47
  • 56