Lodash _.countBy() method
What you’ll learn
- How
_.countBy(collection, iteratee)builds tallies keyed by iteratee results. - Using shorthand iteratees (
"prop",["a","b"]) versus functions. - How this differs from
_.groupBy(arrays per bucket) and hand-rolledreduce. - Try each example in the editor (
?tryit=1,2,3) with Lodash from a CDN.
Prerequisites
Skim the collection methods hub for how Lodash treats arrays and plain objects as collections.
- You understand plain objects as key/value maps.
- You can open Try-it labs or run snippets locally.
Overview
_.countBy answers “how many per bucket?” in one pass—ideal for histogram-style summaries, tag frequency, or bucketing numeric scores without retaining every element.
Compact tallies
Only counts per group land in the result—lighter than storing arrays when you just need totals.
Iteratee flexibility
Functions, property names, or path arrays behave like other Lodash collection helpers.
Arrays or objects
The same API walks arrays or enumerable object properties consistently.
Syntax
_.countBy(collection, iteratee) - collection: array, array-like, or plain object Lodash can iterate.
- iteratee: invoked per element as
(value, key|index, collection); result selects the tally bucket. - Returns: plain object mapping string keys to integer counts.
Bucket numbers with a function iteratee
Floor scores into decade-like bins so each distinct rounded key receives its own running total.
import countBy from "lodash/countBy";
countBy([83, 87, 91, 44, 49], (n) => Math.floor(n / 10) * 10);
// → { "80": 2, "90": 1, "40": 2 } Shorthand: count rows by status
Passing a string iteratee plucks that property from each object—handy for API payloads.
import countBy from "lodash/countBy";
countBy(
[
{ id: 1, status: "open" },
{ id: 2, status: "done" },
{ id: 3, status: "open" }
],
"status"
);
// → { open: 2, done: 1 } Walk a plain object collection
Collections are not limited to arrays—Lodash iterates values and passes both value and key to your iteratee.
import countBy from "lodash/countBy";
countBy(
{ alice: { role: "admin" }, bob: { role: "user" }, carol: { role: "admin" } },
(rec) => rec.role
);
// → { admin: 2, user: 1 } 📋 _.countBy vs groupBy, reduce
| API | Shape of result | Best when |
|---|---|---|
_.countBy(collection, iteratee) | Keys → counts | You only need totals per bucket |
_.groupBy(collection, iteratee) | Keys → element arrays | You still need the grouped rows |
_.reduce(collection, fn, {}) | Custom accumulator | Logic branches beyond simple tally keys |
Pitfalls to avoid
String coercion collisions
Distinct iteratee values can stringify to the same object key—know how your buckets serialize.
Sparse arrays
Holes may be skipped depending on engine paths; normalize arrays before counting critical metrics.
Need items back?
If downstream steps require filtered subsets per bucket, start from groupBy instead of recomputing.
❓ FAQ
Summary
- Purpose:
_.countBy(collection, iteratee)returns tally counts grouped by iteratee output. - Contrast: prefer
_.groupBywhen each bucket must retain elements. - Next: Lodash _.every(), collection hub (previous), or array methods hub.
_.countBy turns each iteratee result into an object key (via String coercion). Objects or arrays as keys become stable string labels—pair that mental model with _.groupBy when you need the raw items per bucket.
6 people found this page helpful
