Reputation: 545
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
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
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
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