Course outline
Full-Stack course / JavaScript fundamentals

Group orders by customer

Lab

How to fetch and submit this exercise

Once: install the tool and connect your account.

curl -fsSL https://gonomicon.com/install.sh | sh
gonomicon login

Each exercise: download it, edit the file named in the instructions, then submit.

gonomicon fetch fs-week-2/03-08-group-orders-by-customer
cd 03-08-group-orders-by-customer
gonomicon submit

The runner depends on the exercise: JavaScript/TypeScript/React labs run with Vitest, Python labs with pytest, and config-file labs (Docker, CI, Terraform, Nginx) are checked by parsing your file. gonomicon test runs the visible checks on your computer first; submitting also runs the hidden checks on our server.

Group orders by customer

Goal: turn a flat list of orders into a Map with one entry per customer, showing how many orders they placed and how much they spent in total.

Worked example

Each order is an object { customer, amount }. For this list:

[
  { customer: "Ana", amount: 20 },
  { customer: "Ben", amount: 5 },
  { customer: "Ana", amount: 10 },
]

groupByCustomer(orders) returns a Map that holds:

Key (customer)Value
"Ana"{ count: 2, total: 30 }
"Ben"{ count: 1, total: 5 }

An empty list gives an empty Map (its size is 0).

Rules

  • Write function groupByCustomer(orders) as a function declaration. It takes the list of orders and returns a Map.
  • Each key is a customer's name, exactly as written in the orders. "ana" and "Ana" are two different customers.
  • Each value is an object with exactly two properties: count (how many orders that customer placed) and total (the sum of their amounts).
  • An order with an amount of 0 still counts as an order.
  • Customers appear in the Map in the order they first show up in the list.
  • Don't change the orders list or the order objects inside it. Build new objects for the result.
  • The tests also try long lists, so walk the orders only once.
  • To try it yourself, add a line such as console.log(groupByCustomer([{ customer: "Ana", amount: 20 }])); at the bottom while you work, then remove it, and run node group_orders_by_customer.js.

What you'll practice

  • Grouping: one pass over the data, one bin per group
  • Using a Map to hold the bins
  • Updating a bin without changing the original data
  • Falling back with ?? the first time a customer is seen

Run it

gonomicon fetch fs-week-2/03-08-group-orders-by-customer
cd 03-08-group-orders-by-customer
gonomicon test
gonomicon submit

Hints

  1. You need one Map entry per customer, so the customer name is the key. Walk the orders once with for...of, and for each order look up what that customer already has.
  2. groups.get(name) gives you the customer's current { count, total }, or undefined the first time you see them. Use ?? to start a new customer at { count: 0, total: 0 }, then groups.set(name, ...) the updated numbers.
  3. Shape: const groups = new Map(); for (const { customer, amount } of orders) { const entry = groups.get(customer) ?? { count: 0, total: 0 }; groups.set(customer, { count: entry.count + 1, total: entry.total + amount }); } return groups;