I people, i need help , i dont know how to handle the object to get what I need using vanilla. I need group by "type" for each "elem", and sum price and discount values, and return them in an array. I would appreciate if someone could explain to me how to approach the transformation.
I have this object
{
"w_elem": [
{
"elem": [
{"type": "type_a","price": "100","discount": "10"},
{"type": "type_b","price": "120","discount": "12"},
{"type": "type_a","price": "165","discount": "10"}
],
"user": "1001",
"userType": "A"
},
{
"elem": [
{"type": "type_a","price": "50","discount": "5"},
{"type": "type_b","price": "15","discount": "0"}
],
"user": "1011",
"userType": "B"
},
{
"elem": [
{"type": "type_a","price": "20","discount": "5"},
{"type": "type_b","price": "15","discount": "0"}
],
"user": "1011",
"userType": "B"
}
]
}
Imust return the following array
[
{"type": "type_a","price": "335","discount":"30"},
{"type":"type_b","price": "150","discount": "12"}
]
i tried the following but im not able to understand.
let helper = {};
const data = newArr.reduce((acc, currElem) => {
currElem.elem.forEach(item => {
if(!helper[currElem.type]) {
helper[currElem.type] = Object.assign({}, currElem);
acc.push(helper[currElem.type])
}else{
helper[currElem.type].price = currElem.price;
helper[currElem.type].discount = currElem.discount;
}
})
return acc;
}, [])
CodePudding user response:
The following code snippet should do the trick.
As for the explanation:
- You want to get a list of all your type objects. You can do this by using flatMap.
- Get all the unique values for type. In ES6 you can use SET to get all unqiue values in a list
- Then you can use filter to get all objects with the same type and subsequently use reduce on only those.
Note: Since count doesn't exist you need to define an initial value for it and since you define count you also have to define the other values you perform a reduce operation on. (No need for id since there since you assign it direclty and the previous value doesn't matter)
I hope you can follow my short explanation.
const newJson = {
"w_elem": [
{
"elem": [
{"type": "type_a","price": "100","discount": "10"},
{"type": "type_b","price": "120","discount": "12"},
{"type": "type_a","price": "165","discount": "10"}
],
"user": "1001",
"userType": "A"
},
{
"elem": [
{"type": "type_a","price": "96.2","discount": "5"},
{"type": "type_b","price": "15","discount": "0"}
],
"user": "1011",
"userType": "B"
},
{
"elem": [
{"type": "type_a","price": "96.2","discount": "5"},
{"type": "type_b","price": "15","discount": "0"}
],
"user": "1011",
"userType": "B"
}
]
}
const newArr = newJson["w_elem"]
/* Get all elem */
const flatElem = newArr.flatMap((item) => {
return item["elem"]
})
const keys = [... new Set(flatElem.map(item => { return item["type"]}))]
let data = keys.map( id => {
return flatElem.filter( obj => obj["type"] === id )
.reduce((acc, cur) => (
{
type: id,
count: acc.count 1,
price: acc.price parseFloat(cur.price),
discount: acc.discount parseFloat(cur.discount)
}
), {count: 0, price: 0, discount: 0})
})
console.log(data)
CodePudding user response:
You can simplify task by making a flat array of elements. And then group summary values by type
.
const data = {"w_elem":[{"elem":[{"type":"type_a","price":"100","discount":"10"},{"type":"type_b","price":"120","discount":"12"},{"type":"type_a","price":"165","discount":"10"}],"user":"1001","userType":"A"},{"elem":[{"type":"type_a","price":"96.2","discount":"5"},{"type":"type_b","price":"15","discount":"0"}],"user":"1011","userType":"B"},{"elem":[{"type":"type_a","price":"96.2","discount":"5"},{"type":"type_b","price":"15","discount":"0"}],"user":"1011","userType":"B"}]};
const elems = data.w_elem.flatMap(({ elem }) => elem);
const result = Object.values(elems.reduce((acc, { type, price, discount }) => {
acc[type] ??= { type, count: 0, price: 0, discount: 0 };
acc[type].count = 1;
acc[type].price = Number(price);
acc[type].discount = Number(discount);
return acc;
}, {}));
console.log(result);
.as-console-wrapper{min-height: 100%!important; top: 0}