简体   繁体   中英

Looping an array of object literals and matching customers

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM