Reputation: 83
Consider an array of objects
myArray = [
{date: 'date1', amount: 1},
{date: 'date1', amount: 2},
{date: 'date2', amount: 3},
{date: 'date2', amount: 4},
]
I want to end up with values summed in a object like so:
{
date1: 3,
date2: 7
}
This works:
let myObj = {}
myArray.forEach(arrayObj=>{
myObj[arrayObj.date] ? myObj[arrayObj.date] += arrayObj.amount : myObj[arrayObj.date] = obj.amount
})
This would be cleaner but does not work
let myObj = {}
myArray.forEach(arrayObj=>{
myObj[arrayObj.date] += arrayObj.amount
})
Question: is there a way to do this without checking for the existence of the property?
Upvotes: 1
Views: 45
Reputation: 215009
You can utilize a Proxy
to create a DefaultDict
object, similar to that in python. DefaultDict
returns a predefined value for missing keys, instead of undefined
.
function DefaultDict(value) {
return new Proxy({}, {
get(target, key) {
return key in target ? target[key] : value
}
})
}
// example:
myArray = [
{date: 'date1', amount: 1},
{date: 'date1', amount: 2},
{date: 'date2', amount: 3},
{date: 'date2', amount: 4},
]
myObj = DefaultDict(0)
myArray.forEach(v => myObj[v.date] += v.amount)
console.log(myObj)
Upvotes: 1
Reputation: 370989
There's no way to get around repeating myObj[arrayObj.date]
twice, but you can make things shorter by unconditionally assigning to it, and alternating ||
it with 0.
myArray = [
{date: 'date1', amount: 1},
{date: 'date1', amount: 2},
{date: 'date2', amount: 3},
{date: 'date2', amount: 4},
]
const result = {};
for (const { date, amount } of myArray) {
result[date] = (result[date] || 0) + amount;
}
console.log(result);
Upvotes: 1