Calculating average spending per user from array of purchase records in JavaScript

I need assistance figuring out how to calculate the average spending for each customer from a collection of purchase records. Here’s how my data looks:

const purchases = [
  { buyer: "Emma", price: 180 },
  { buyer: "John", price: 320 },
  { buyer: "Emma", price: 220 },
  { buyer: "Mike", price: 250 },
  { buyer: "John", price: 160 },
  { buyer: "Sara", price: 90 },
  { buyer: "Mike", price: 140 }
];

Here’s my current code:

function calculateAverageSpending(data) {
  const totals = {};
  data.forEach(record => {
    const buyer = record.buyer;
    totals[buyer] = (totals[buyer] || 0) + record.price;
  });

  const averages = {};
  for (const spending in totals) {
    if (totals.hasOwnProperty(spending) && typeof spending === 'number') {
      averages[spending] = totals[spending] / 2; // Incorrect divisor in this part
    }
  }

  return averages;
}

console.log(calculateAverageSpending(purchases));

I can successfully gather the total transaction amount per customer, but I’m unsure how to accurately divide by the number of transactions made. My objective is to receive an object like this:

{
  Emma: 200,
  John: 240,
  Mike: 195,
  Sara: 90
}

Each value should represent the average amount spent by that customer. Any guidance would be greatly appreciated!

you could also use reduce to make it cleaner, just track counts separately. the typeof check is wrong since buyer names are strings not numbers btw

The main issue with your code is in the condition check and the hardcoded divisor. You’re checking typeof spending === 'number' but spending is actually the buyer’s name (a string), not a number. Also, you’re dividing by 2 instead of the actual transaction count.

You need to track both totals and counts simultaneously. Here’s a corrected approach:

function calculateAverageSpending(data) {
  const buyerStats = {};
  
  data.forEach(record => {
    const buyer = record.buyer;
    if (!buyerStats[buyer]) {
      buyerStats[buyer] = { total: 0, count: 0 };
    }
    buyerStats[buyer].total += record.price;
    buyerStats[buyer].count += 1;
  });

  const averages = {};
  for (const buyer in buyerStats) {
    averages[buyer] = buyerStats[buyer].total / buyerStats[buyer].count;
  }

  return averages;
}

This tracks both the running total and transaction count for each buyer, then calculates the proper average by dividing total by count.

I ran into a similar problem a few months back when working on sales analytics. The core issue is that you’re not actually counting transactions per buyer. Your loop variable spending contains the buyer names as strings, so the typeof spending === 'number' condition never evaluates to true, which is why you get an empty result.

Here’s what worked for me - I modified your existing approach by adding a separate counts object:

function calculateAverageSpending(data) {
  const totals = {};
  const counts = {};
  
  data.forEach(record => {
    const buyer = record.buyer;
    totals[buyer] = (totals[buyer] || 0) + record.price;
    counts[buyer] = (counts[buyer] || 0) + 1;
  });

  const averages = {};
  for (const buyer in totals) {
    averages[buyer] = totals[buyer] / counts[buyer];
  }
  
  return averages;
}

This keeps your original structure mostly intact while properly tracking transaction counts. The key insight is maintaining parallel objects for totals and counts, then dividing appropriately.