This is probably something really stupid that I am overthinking or just not thinking of at all (been awake for almost 30 hours so more than likely).
I have an array of "sales", see below:
let sales = [
{
amount: 100,
customerName: "Johan"
},
{
amount: 262,
customerName: "James"
},
{
amount: 42,
customerName: "Fraser"
},
{
amount: 983,
customerName: "Calum"
},
{
amount: 246,
customerName: "Johan"
}
,
{
amount: 873,
customerName: "James"
}
,
{
amount: 210,
customerName: "Fraser"
},
{
amount: 68,
customerName: "Calum"
}
];
What I am trying to do is loop over the array and instead of 2 records for each customer, I would like 1 record but the total should be all the amounts related to that customer added together.
I tried using sales.forEach
and then pushing the values to a new array... this just made the same array again.. basically.
I also tried using sales.reduce
but my output didnt do what I described above, instead it still made 2 records, except the second record had added the totals.
I have had a look around and even on here, there isn't anything exactly like what I am looking for.
I want to do this in pure javascript.
If you need clarifications, just ask in the comments, instead of marking down!
There are a couple of ways doing this, here's one with reduce:
sales.reduce((newSales, item) => {
const existingItem = newSales.find(el => el.customerName === item.customerName);
// it exists, add to the existing one
if (existingItem) { existingItem.amount += item.amount; }
// it doesn't exist, add the one we have
else { newSales.push(item); }
return newSales;
}, []); // start with an empty array.
You can try something like this:
var sales = [ { amount: 100, customerName: "Johan"}, { amount: 262, customerName: "James"}, { amount: 42, customerName: "Fraser"}, { amount: 983, customerName: "Calum"}, { amount: 246, customerName: "Johan"}, { amount: 873, customerName: "James"}, { amount: 210, customerName: "Fraser"}, { amount: 68, customerName: "Calum"}]; var _tmp = {}; // Sort array using customer name sales.sort(function(a,b){ if(a.customerName < b.customerName) return -1; if(a.customerName > b.customerName) return 1; return 0; }) // Find and remove duplicate entries .forEach(function(item){ _tmp[item.customerName] = (_tmp[item.customerName] || 0) + item.amount; }); // Create final result var result = []; Object.keys(_tmp).forEach(function(key){ result.push({"customerName":key, "amount": _tmp[key]}); }); document.write("<pre>" + JSON.stringify(result,0,4) + "</pre>")
var sales = [{
amount: 100,
customerName: "Johan"
}, {
amount: 262,
customerName: "James"
}, {
amount: 42,
customerName: "Fraser"
}, {
amount: 983,
customerName: "Calum"
}, {
amount: 246,
customerName: "Johan"
}, {
amount: 873,
customerName: "James"
}, {
amount: 210,
customerName: "Fraser"
}, {
amount: 68,
customerName: "Calum"
}];
var reduced_sales = sales
.reduce(function (prev, curr) {
var prev_amount = prev[curr.customerName] || 0
prev[curr.customerName] = prev_amount + curr.amount
return prev;
}, {});
var sales_final = [];
for (var prop in reduced_sales) {
sales_final.push({
amount: reduced_sales[prop],
customerName: prop
}
);
}
console.log(sales_final);
You can use a for..in
loop, Array.prototype.forEach()
var names = [], amounts = [], res = [];
for (var prop in sales) {
var n = sales[prop].customerName;
var a = sales[prop].amount;
var index = names.indexOf(n);
if (index == -1) {
names.push(n);
amounts.push(a);
} else {
amounts[index] += a;
}
};
names.forEach(function(name, key) {
// populate `res` array with results contained in `names`, `amounts`
res[key] = {customerName:name, amount:amounts[key]}
});
Perhaps easiest way is to convert to map
var salesByCustomerName = {};
for (var i = 0; i < sales.length; i++)
{
var sale = sales[i], customerName = sale.customerName;
salesByCustomerName[customerName] =
(salesByCustomerName[customerName] || 0) + sale.amount;
}
// Firebug prints: Object { Johan: 346, James: 1135, Fraser: 252, Calum: 1051 }
console.log(salesByCustomerName);
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.