问题
I have an object, the format is such:
let obj= {
'Jan 01': [
{dt: 'Jan 01', cat: 'abc', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'abc', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'abc', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'pqr', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'pqr', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'pqr', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'xyz', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'xyz', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'xyz', site: 'jeeves', val1:67, val2:78, val3:12}
],
'Feb 01': [
{dt: 'Feb 01', cat: 'abc', site: 'google', val1:12, val2:11, val3:41},
{dt: 'Feb 01', cat: 'abc', site: 'bing', val1:45, val2:67, val3:0},
{dt: 'Feb 01', cat: 'abc', site: 'jeeves', val1:78, val2:34, val3:41},
{dt: 'Feb 01', cat: 'pqr', site: 'google', val1:44, val2:88, val3:5},
{dt: 'Feb 01', cat: 'pqr', site: 'bing', val1:56, val2:11, val3:99},
{dt: 'Feb 01', cat: 'pqr', site: 'jeeves', val1:22, val2:34, val3:77},
{dt: 'Feb 01', cat: 'xyz', site: 'google', val1:33, val2:99, val3:34},
{dt: 'Feb 01', cat: 'xyz', site: 'bing', val1:77, val2:55, val3:14},
{dt: 'Feb 01', cat: 'xyz', site: 'jeeves', val1:33, val2:23, val3:98}
],
'Mar 01': [
{dt: 'Mar 01', cat: 'abc', site: 'google', val1:11, val2:20, val3:6},
{dt: 'Mar 01', cat: 'abc', site: 'bing', val1:22, val2:91, val3:89},
{dt: 'Mar 01', cat: 'abc', site: 'jeeves', val1:33, val2:81, val3:12},
{dt: 'Mar 01', cat: 'pqr', site: 'google', val1:44, val2:71, val3:33},
{dt: 'Mar 01', cat: 'pqr', site: 'bing', val1:55, val2:61, val3:14},
{dt: 'Mar 01', cat: 'pqr', site: 'jeeves', val1:66, val2:51, val3:43},
{dt: 'Mar 01', cat: 'xyz', site: 'google', val1:77, val2:41, val3:98},
{dt: 'Mar 01', cat: 'xyz', site: 'bing', val1:88, val2:31, val3:23},
{dt: 'Mar 01', cat: 'xyz', site: 'jeeves', val1:99, val2:21, val3:4}
]
}
I want to sum the values of val1
, based on 2 of the values inside my object. I want to sum the values based on dt
and cat
.
I know how to sum the values based on the keys:
let group = Object.entries(obj).map(([key, group]) => ({
['dt']: key, // because it is similar to the key
['val1']: group.map(entry => entry[val1]).reduce((pv, cv) => {
return pv + (parseFloat(cv) || 0);,
['val2']: group.map(entry => entry[val2]).reduce((pv, cv) => {
return pv + (parseFloat(cv) || 0);,
['val3']: group.map(entry => entry[val3]).reduce((pv, cv) => {
return pv + (parseFloat(cv) || 0);,
}));
How do I sum based on dt
and cat
? I need my final value to be:
let obj= {
'Jan 01': [
{dt: 'Jan 01', cat: 'abc', val1:100, val2:110, val3:56},
{dt: 'Jan 01', cat: 'pqr', val1:100, val2:110, val3:56},
{dt: 'Jan 01', cat: 'xyz', val1:100, val2:110, val3:56},
],
'Feb 01': [
{dt: 'Feb 01', cat: 'abc', val1:135, val2:112, val3:82},
{dt: 'Feb 01', cat: 'pqr', val1:122, val2:133, val3:181},
{dt: 'Feb 01', cat: 'xyz', val1:143, val2:177, val3:146}
],
'Mar 01': [
{dt: 'Mar 01', cat: 'abc', val1:66, val2:192, val3:107},
{dt: 'Mar 01', cat: 'pqr', val1:165, val2:183, val3:90},
{dt: 'Mar 01', cat: 'xyz', val1:264, val2:93, val3:125}
]
}
Or even dt
and site
.
I want to be able to group based on 2 values. Is that possible?
回答1:
Use dt+','+cat
as a key in a Map to track dupes. sum up all the other keys.
assumes any keys other than site dt and cat are vals.
for(const key of Object.keys(obj)) {
const catMap = new Map()
for(const {site, dt, cat, ...vals} of obj[key]) {
const row = catMap.get(dt+','+cat)||{dt, cat}
Object.entries(vals).forEach(([k,v])=>row[k]=(row[k]||0)+v)
catMap.set(dt+','+cat, row)
}
obj[key] = [...catMap.values()]
}
console.log(
obj
)
<script>
let obj= {
'Jan 01': [
{dt: 'Jan 01', cat: 'abc', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'abc', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'abc', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'pqr', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'pqr', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'pqr', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'xyz', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'xyz', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'xyz', site: 'jeeves', val1:67, val2:78, val3:12}
],
'Feb 01': [
{dt: 'Feb 01', cat: 'abc', site: 'google', val1:12, val2:11, val3:41},
{dt: 'Feb 01', cat: 'abc', site: 'bing', val1:45, val2:67, val3:0},
{dt: 'Feb 01', cat: 'abc', site: 'jeeves', val1:78, val2:34, val3:41},
{dt: 'Feb 01', cat: 'pqr', site: 'google', val1:44, val2:88, val3:5},
{dt: 'Feb 01', cat: 'pqr', site: 'bing', val1:56, val2:11, val3:99},
{dt: 'Feb 01', cat: 'pqr', site: 'jeeves', val1:22, val2:34, val3:77},
{dt: 'Feb 01', cat: 'xyz', site: 'google', val1:33, val2:99, val3:34},
{dt: 'Feb 01', cat: 'xyz', site: 'bing', val1:77, val2:55, val3:14},
{dt: 'Feb 01', cat: 'xyz', site: 'jeeves', val1:33, val2:23, val3:98}
],
'Mar 01': [
{dt: 'Mar 01', cat: 'abc', site: 'google', val1:11, val2:20, val3:6},
{dt: 'Mar 01', cat: 'abc', site: 'bing', val1:22, val2:91, val3:89},
{dt: 'Mar 01', cat: 'abc', site: 'jeeves', val1:33, val2:81, val3:12},
{dt: 'Mar 01', cat: 'pqr', site: 'google', val1:44, val2:71, val3:33},
{dt: 'Mar 01', cat: 'pqr', site: 'bing', val1:55, val2:61, val3:14},
{dt: 'Mar 01', cat: 'pqr', site: 'jeeves', val1:66, val2:51, val3:43},
{dt: 'Mar 01', cat: 'xyz', site: 'google', val1:77, val2:41, val3:98},
{dt: 'Mar 01', cat: 'xyz', site: 'bing', val1:88, val2:31, val3:23},
{dt: 'Mar 01', cat: 'xyz', site: 'jeeves', val1:99, val2:21, val3:4}
]
}
</script>
回答2:
Here is a different approach using reduce
let objx= {
'Jan 01': [
{dt: 'Jan 01', cat: 'abc', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'abc', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'abc', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'pqr', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'pqr', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'pqr', site: 'jeeves', val1:67, val2:78, val3:12},
{dt: 'Jan 01', cat: 'xyz', site: 'google', val1:10, val2:20, val3:30},
{dt: 'Jan 01', cat: 'xyz', site: 'bing', val1:23, val2:12, val3:14},
{dt: 'Jan 01', cat: 'xyz', site: 'jeeves', val1:67, val2:78, val3:12}
],
'Feb 01': [
{dt: 'Feb 01', cat: 'abc', site: 'google', val1:12, val2:11, val3:41},
{dt: 'Feb 01', cat: 'abc', site: 'bing', val1:45, val2:67, val3:0},
{dt: 'Feb 01', cat: 'abc', site: 'jeeves', val1:78, val2:34, val3:41},
{dt: 'Feb 01', cat: 'pqr', site: 'google', val1:44, val2:88, val3:5},
{dt: 'Feb 01', cat: 'pqr', site: 'bing', val1:56, val2:11, val3:99},
{dt: 'Feb 01', cat: 'pqr', site: 'jeeves', val1:22, val2:34, val3:77},
{dt: 'Feb 01', cat: 'xyz', site: 'google', val1:33, val2:99, val3:34},
{dt: 'Feb 01', cat: 'xyz', site: 'bing', val1:77, val2:55, val3:14},
{dt: 'Feb 01', cat: 'xyz', site: 'jeeves', val1:33, val2:23, val3:98}
],
'Mar 01': [
{dt: 'Mar 01', cat: 'abc', site: 'google', val1:11, val2:20, val3:6},
{dt: 'Mar 01', cat: 'abc', site: 'bing', val1:22, val2:91, val3:89},
{dt: 'Mar 01', cat: 'abc', site: 'jeeves', val1:33, val2:81, val3:12},
{dt: 'Mar 01', cat: 'pqr', site: 'google', val1:44, val2:71, val3:33},
{dt: 'Mar 01', cat: 'pqr', site: 'bing', val1:55, val2:61, val3:14},
{dt: 'Mar 01', cat: 'pqr', site: 'jeeves', val1:66, val2:51, val3:43},
{dt: 'Mar 01', cat: 'xyz', site: 'google', val1:77, val2:41, val3:98},
{dt: 'Mar 01', cat: 'xyz', site: 'bing', val1:88, val2:31, val3:23},
{dt: 'Mar 01', cat: 'xyz', site: 'jeeves', val1:99, val2:21, val3:4}
]
}
fo={}
for(let o of Object.entries(objx)){
fo[o[0]]=[]
o[1].reduce((acc,curr,i)=>{
return curr.dt==acc.dt && acc.cat==curr.cat? (acc= {...acc,...{...curr,['val1']:acc.val1+curr.val1, ['val2']:acc.val2+curr.val2, ['val3']:acc.val3+curr.val3}}
,i!=o[1].length-1 ? acc : (delete acc.site ,fo[o[0]].push(acc))): (delete acc.site,fo[o[0]].push(acc) , acc=curr)
})
}
console.log(fo)
来源:https://stackoverflow.com/questions/62545906/sum-values-of-objects-based-on-other-values-in-object