Problems › TypeScript › reporting
Average spend per category
A budgeting view shows what a typical transaction looks like in each category.
- Amounts are never negative.
- The average is a whole number, rounded half up: 12.5 becomes 13.
- A category with no entries never appears.
averagePerCategory(entries: list<Entry>) → map<string, int>
Where you start
function averagePerCategory(entries: Entry[]): Record<string, number> {
}
Worked examples
| Call | Result |
|---|---|
averagePerCategory([{"category":"food","amount":10},{"category":"food","amount":15}]) | {"food":13} |
averagePerCategory([{"category":"rent","amount":3000},{"category":"food","amount":40},{"category":"food","amount":20}]) | {"rent":3000,"food":30} |
averagePerCategory([{"category":"x","amount":0}]) | {"x":0} |
averagePerCategory([]) | {} |
Hint
Collect sums and counts side by side, then divide once at the end. (sum + count / 2) / count rounds half up in integers.
Reference solution in TypeScript
function averagePerCategory(entries: Entry[]): Record<string, number> {
const sums = new Map<string, number>();
const counts = new Map<string, number>();
for (const e of entries) {
sums.set(e.category, (sums.get(e.category) || 0) + e.amount);
counts.set(e.category, (counts.get(e.category) || 0) + 1);
}
const result: Record<string, number> = {};
for (const [k, s] of sums) {
const n = counts.get(k)!;
result[k] = Math.floor((s + Math.floor(n / 2)) / n);
}
return result;
}