Another solution would be to use Map
(not Array.prototype.map) as it has several notable differences compared to objects:
var data = [{
costOfAirtickets: 2500,
costOfHotel: 1200
}, {
costOfAirtickets: 1500,
costOfHotel: 1000
}]
let sums = data.reduce((collection,rcd)=>{
Object.entries(rcd).forEach(([key,value])=>{
let sum = collection.get(key) || 0
collection.set(key, sum + +value)
})
return collection
}, new Map())
console.log(...sums.entries())
Explanation
Outer loop
The above first iterates over your data
array using the reduce
method. Each object within that I'll be referring to as a record -- distinguished in the code via the variable, rcd
.
Each iteration of reduce returns a value which is passed as the first argument to the next iteration of the loop. In this case, the parameter collection
holds that argument, which is your set of sums.
Inner loop
Within the reduce
loop, each key/value pair of the record is iterated over using forEach
. To get the key/value pair the Object.entries
method is used. Using array destructuring these arguments can be directly assigned to the respective variables, key
and value
Retrieving/Setting values
Unlike a primitive object, Map
has its own methods for getting and setting its entries using get()
and set()
. So first retrieve the previous sum using get()
, if it's not set then default to 0
, which is what the || 0
does. At that point, you can assume the previous sum is at least 0 or greater and add the current key's value onto it.
Alternatives to Map
If you find Map is a bit heavy-handed, you may also use a similar object such as Set, which has many of the same methods (except the get()
), or you could also use a primitive object (i.e. {}
).