I am trying to create new array of object with total data by year(or any selected key) but, it doesn't work as expected.
const dataArray = [
{
"abc": 10,
"xyz": 20,
"year": "2021"
},
{
"abc": 20,
"xyz": 20,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 30,
"xyz": 10,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 10,
"xyz": 10,
"year": "2022"
}
]
const keys = ["year", "abc", "xyz"];
const cols = ["year"]
//expected
//[{ "abc": total of abc for 2021, "xyz": total of xyz for 2021, "year" "2021"}, { "abc": total of abc for 2022, "xyz": total of xyz for 2022, "year" "2022"}]
const newObject = {};
cols.forEach(col => {
dataArray.forEach(arr => {
keys.forEach(key => {
if(col != key) {
newObject[key] += col[key]
}
})
})
})
console.log(newObject);
I tried above but doesn't work as expected.
My expectation is:
[
{
"abc": "total of abc for 2021",
"xyz": "total of xyz for 2021",
"year": "2021"
},
{
"abc": "total of abc for 2022",
"xyz": "total of xyz for 2022",
"year": "2022"
}
]
You can aggregate dataArray using reduce, building an object whose keys are the year values and values are the accumulated abc and xyz values. You can then convert that into your desired array format using Object.values:
const dataArray = [{
"abc": 10, "xyz": 20, "year": "2021"
},
{
"abc": 20, "xyz": 20, "year": "2022"
},
{
"abc": 20, "xyz": 10, "year": "2021"
},
{
"abc": 30, "xyz": 10, "year": "2022"
},
{
"abc": 20, "xyz": 10, "year": "2021"
},
{
"abc": 10, "xyz": 10, "year": "2022"
}
]
const keys = ["year", "abc", "xyz"];
const cols = ["year"]
newObject = Object.values(
dataArray.reduce((acc, obj) => {
colkey = cols.map(k => obj[k]).join('##')
if (acc.hasOwnProperty(colkey)) {
keys.filter(k => !cols.includes(k)).forEach(k => acc[colkey][k] += obj[k])
} else {
acc[colkey] = obj
}
return acc
}, {})
);
console.log(newObject);
.as-console-wrapper { max-height: 100% !important }
const dataArray = [
{
"abc": 10,
"xyz": 20,
"year": "2021"
},
{
"abc": 20,
"xyz": 20,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 30,
"xyz": 10,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 10,
"xyz": 10,
"year": "2022"
}
]
const result = dataArray.reduce((res, ele) => {
let exist = res.find(e => e.year === ele.year)
if(exist) {
exist.abc += ele.abc
exist.xyz += ele.xyz
} else {
res = [...res, {...ele}]
}
return res
}, [])
// other way
const result1 = Object.values(
dataArray.reduce((res, {year, ...rest}) => {
let ele = res[year] ??= {year}
Object.entries(rest).forEach(([k, v]) => ele[k] = (ele[k] ?? 0) + v)
return res
}, {})
)
console.log(result, result1)
if you want some different approach
const dataArray = [
{
"abc": 10,
"xyz": 20,
"year": "2021"
},
{
"abc": 20,
"xyz": 20,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 30,
"xyz": 10,
"year": "2022"
},
{
"abc": 20,
"xyz": 10,
"year": "2021"
},
{
"abc": 10,
"xyz": 10,
"year": "2022"
}
]
let mainObj = {}
dataArray.forEach((el)=>{
if(!mainObj.hasOwnProperty(el.year)){
mainObj[el.year] = {}
mainObj[el.year].abc = el.abc
mainObj[el.year].xyz = el.xyz
mainObj[el.year].year = el.year
}
else{
mainObj[el.year].abc = mainObj[el.year].abc + el.abc
mainObj[el.year].xyz = mainObj[el.year].xyz + el.xyz
}
})
let values = Object.values(mainObj)
console.log(values)