Problems › TypeScript › reporting
The best selling products this week
The weekly email lists the top products by units sold. Sales come in one row per transaction, so the same product appears many times.
- Add up the units per product name first.
- Order by units sold, largest first; products level on units go alphabetically.
- Return at most `howMany` names, or fewer if there are not that many products.
- Asking for zero or fewer returns nothing.
topSellers(sales: list<Sale>, howMany: int) → list<string>
Where you start
function topSellers(sales: Sale[], howMany: number): string[] {
}
Worked examples
| Call | Result |
|---|---|
topSellers([{"name":"mug","qty":5},{"name":"pen","qty":3},{"name":"mug","qty":2}], 2) | ["mug","pen"] |
topSellers([{"name":"zip","qty":1},{"name":"ace","qty":1}], 2) | ["ace","zip"] |
topSellers([{"name":"mug","qty":5},{"name":"pen","qty":9}], 1) | ["pen"] |
topSellers([{"name":"mug","qty":5}], 0) | [] |
Hint
Aggregate into a map, then sort the entries. The tie-break is what most solutions forget.
Reference solution in TypeScript
function topSellers(sales: Sale[], howMany: number): string[] {
const totals = new Map<string, number>();
for (const s of sales) totals.set(s.name, (totals.get(s.name) || 0) + s.qty);
const names = [...totals.keys()];
names.sort((a, b) => totals.get(b)! - totals.get(a)! || (a < b ? -1 : a > b ? 1 : 0));
return howMany <= 0 ? [] : names.slice(0, howMany);
}