JenuRudan
JenuRudan

Reputation: 545

Javascript - Add two hash maps

I have two hash maps as follows

m1={};
m1['a']={};
m1['b']={};
m1['a']['x']=5;
m1['b']['x']=6;
m1['a']['y']=4;
m1['b']['y']=6;

m2={};
m2['a']={};
m2['b']={};
m2['a']['x']=8;
m2['b']['x']=7;
m2['a']['y']=6;
m2['b']['y']=4;

output expected
m3['a']['x']->13;
m3['a']['y']->10;
m3['b']['x']->13;
m3['b']['y']->10;

an easy solution is to loop through each map and add values to new map, but is there a more efficient way ?

Upvotes: 0

Views: 57

Answers (3)

Eddie
Eddie

Reputation: 26844

You can use Object.entries to convert the object into an array. Summarize the array using reduce

let m1 = {};
m1['a'] = {};
m1['b'] = {};
m1['a']['x'] = 5;
m1['b']['x'] = 6;
m1['a']['y'] = 4;
m1['b']['y'] = 6;


let m2 = {};
m2['a'] = {};
m2['b'] = {};
m2['a']['x'] = 8;
m2['b']['x'] = 7;
m2['a']['y'] = 6;
m2['b']['y'] = 4;
m2['a']['z'] = "name";

let m3 = Object.entries(m1).reduce((c, [i, v]) => {
  let addOnly = ['x', 'y'];
  c[i] = c[i] || {};

  //Loop thru m1
  Object.entries(v).reduce((x, [k, o]) => Object.assign(x, {[k]: o}), c[i]);

  //Loop thru m2 
  Object.entries(m2[i]).reduce((x, [k, o]) => {

    if (addOnly.includes(k)) {
      x[k] = x[k] || 0;
      x[k] += o;
    } else {
      x[k] = x[k] || o;
    }

    return x;
  }, c[i]);

  return c;
}, {})

console.log(m3);

Upvotes: 1

Mark
Mark

Reputation: 92440

As long as we're over-engineering this why not calculate the values when you need them rather than in a loop ;)

let m1 = { a: { x: 5, y: 4 }, b: { x: 6, y: 6 } };
let m2 = { a: { x: 8, y: 6 }, b: { x: 7, y: 4 } };

let m3 = new Proxy({}, {
    get: function(target, ab) {
            return new Proxy({}, {
                get: function(target,xy) {
                    return m1[ab][xy] + m2[ab][xy]
                }
            })
        }
    }
);
console.log(m3['a']['y'])
console.log(m3['b']['x'])

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386654

You could check if the value is an object and create a new object with a recursive call of the merge function. Otherwise return the result of the addition.

function merge(o1, o2) {
    return o1 && typeof o1 === 'object'
        ? Object.assign(...Object.keys(o1).map(k => ({ [k]: merge(o1[k], o2[k]) })))
        : o1 + o2;
}

var m1 = { a: { x: 5, y: 4 }, b: { x: 6, y: 6 } },
    m2 = { a: { x: 8, y: 6 }, b: { x: 7, y: 4 } };

console.log(merge(m1, m2));

Upvotes: 1

Related Questions