I have a requirement where i need to find sum the values of amt in different objects having same name. Below is the code snippet
traveler = [
{ description: 'Senior', Amount: 50},
{ description: 'Senior', Amount: 50},
{ description: 'Adult', Amount: 75},
{ description: 'Child', Amount: 35},
{ description: 'Infant', Amount: 25 },
];
Here i want to caluclate the total sum of Amount in different objects with same description. eg: object 0 and 1 contains same description 'Senior' so the total amt is 100
How to achieve this in angular2?
Should i use inner forloops or is there any better approach? Please help me
You can use reduce
to group the array into an object.
let traveler = [{"description":"Senior","Amount":50},{"description":"Senior","Amount":50},{"description":"Adult","Amount":75},{"description":"Child","Amount":35},{"description":"Infant","Amount":25}] let result = traveler.reduce((c, v) => { c[v.description] = (c[v.description] || 0) + v.Amount; return c; }, {}); console.log(result);
You could take a Map
for collecting the values and render an array of objects with the grouped result.
var traveler = [{ description: 'Senior', amount: 50 }, { description: 'Senior', amount: 50 }, { description: 'Adult', amount: 75 }, { description: 'Child', amount: 35 }, { description: 'Infant', amount: 25 }], grouped = Array.from( traveler.reduce( (m, { description, amount }) => m.set(description, (m.get(description) || 0) + amount), new Map ).entries(), ([description, amount]) => ({ description, amount }) ); console.log(grouped);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I think you should use array#reduce
method to do something like this perhaps:
let traveler = [ { description: 'Senior', Amount: 50}, { description: 'Senior', Amount: 50}, { description: 'Adult', Amount: 75}, { description: 'Child', Amount: 35}, { description: 'Infant', Amount: 25 }, ]; function sumFinder(description) { return traveler.reduce((sum, e) => { (e.description == description) ? (sum += e.Amount) : (sum += 0) return sum; }, 0); } console.log(sumFinder('Senior'));
Use Array.reduce()
to get this output:
var traveler = [ { description: 'Senior', Amount: 50}, { description: 'Senior', Amount: 50}, { description: 'Adult', Amount: 75}, { description: 'Child', Amount: 35}, { description: 'Infant', Amount: 25 }, ]; var res = traveler.reduce((acc, obj)=>{ var existItem = acc.find(item => item.description === obj.description); if(existItem){ existItem.Amount += obj.Amount; return acc; } acc.push(obj); return acc; }, []); console.log(res);
You can do it using rxjs among others:
travelers = [
{ description: 'Senior', amount: 50},
{ description: 'Senior', amount: 50},
{ description: 'Adult', amount: 75},
{ description: 'Child', amount: 35},
{ description: 'Infant', amount: 25 }
];
//emit each person
const source = Rx.Observable.from(travelers);
//group by description
const example = source
.groupBy(traveler => traveler.description)
//return each item in group as array
.mergeMap(group => group.toArray())
const reducer = (accumulator, currentValue) => {return accumulator + currentValue.amount};
const subscribe = example.subscribe(
val =>
console.log(
{
description: val[0].description,
amount: val.reduce( reducer, 0 )
}
)
);
This code's output is what you want:
[object Object] {
amount: 100,
description: "Senior"
}
[object Object] {
amount: 75,
description: "Adult"
}
[object Object] {
amount: 35,
description: "Child"
}
[object Object] {
amount: 25,
description: "Infant"
}
Finally, here is a JSBin you can play with: http://jsbin.com/kacoqulike/1/edit?js,console
A clean and simple solution with Array.prototype.reduce
and ES6 Object assignment desctructuring:
const traveler = [{"description":"Senior","Amount":50},{"description":"Senior","Amount":50},{"description":"Adult","Amount":75},{"description":"Child","Amount":35},{"description":"Infant","Amount":25}]
const result = traveler.reduce((all, {description: d, Amount: a}) => {
all[d] = (all[d] || 0) + a;
return all;
}, {});
console.log(result);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.