Skip to main content

countBy()

countBy<T>(array, iteratee): Record<string, number>

Counts elements by a key derived from each element.

note

Keys are always strings (JavaScript object behavior).


Type Parameters​

T: T​

The type of elements in the array.


Parameters​

array: readonly T[]​

The array to iterate over.

iteratee: (value) => string | number​

A function that returns the grouping key for each element.


Returns: Record<string, number>​

An object with keys and their occurrence counts.


Since​

2.0.0


Performance​

O(n) time & space, uses for loop to avoid array method overhead.


Also known as​

count (Modern Dash) · countBy (Lodash, es-toolkit, Remeda, Ramda) · counting (Radashi) · ❌ (Effect, Antfu)


Example​

countBy([1.2, 1.8, 2.1, 2.9], Math.floor);
// => { '1': 2, '2': 2 }

countBy(
[{ age: 25 }, { age: 30 }, { age: 25 }],
(u) => u.age
);
// => { '25': 2, '30': 1 }

How it works?​

Groups elements by a computed key and counts occurrences instead of collecting elements.

With iteratee function​


Use Cases​

Count items by status/category πŸ“Œβ€‹

Count occurrences of each status or category in a collection. Essential for dashboards, admin panels, and e-commerce analytics.

const orders = [
{ id: 1, status: "pending" },
{ id: 2, status: "shipped" },
{ id: 3, status: "pending" },
];

countBy(orders, (order) => order.status);
// => { pending: 2, shipped: 1 }

Count occurrences in simple arrays​

Count frequency of each value in a flat array. Useful for surveys, polls, and frequency analysis.

const responses = ["yes", "no", "yes", "yes", "no"];

countBy(responses, (r) => r);
// => { yes: 3, no: 2 }

Count by computed key​

Count items grouped by a derived or calculated value. Useful for segmentation and conditional grouping.

const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 17 },
{ name: "Charlie", age: 32 },
];

countBy(users, (user) => (user.age >= 18 ? "adult" : "minor"));
// => { adult: 2, minor: 1 }

Display badge counts in navigation​

Compute counts per category to display as badges in a sidebar or nav bar. Universal pattern for any app with "Inbox (3)", "Pending (12)", or "Errors (5)".

const tickets = [
{ id: 1, status: "open" },
{ id: 2, status: "open" },
{ id: 3, status: "closed" },
{ id: 4, status: "in-progress" },
{ id: 5, status: "open" },
];

const counts = countBy(tickets, (t) => t.status);
// => { open: 3, closed: 1, "in-progress": 1 }

// Render in sidebar
// πŸ“¬ Open (3)
// πŸ”„ In Progress (1)
// βœ… Closed (1)

Count errors by type for monitoring charts​

Aggregate error counts by type for a monitoring dashboard chart. Essential for observability dashboards and incident triage.

const errors = [
{ type: "TypeError", message: "Cannot read property..." },
{ type: "NetworkError", message: "Failed to fetch" },
{ type: "TypeError", message: "undefined is not a function" },
{ type: "SyntaxError", message: "Unexpected token" },
{ type: "NetworkError", message: "Timeout" },
{ type: "NetworkError", message: "DNS resolution failed" },
];

const errorCounts = countBy(errors, (e) => e.type);
// => { TypeError: 2, NetworkError: 3, SyntaxError: 1 }

// Render as pie chart
renderPieChart(Object.entries(errorCounts).map(([type, count]) => ({ label: type, value: count })));