Count ByLoading saved progress…

Count By

Implement countBy(collection, iteratee) — walk an array and tally how many elements fall into each bucket, where the bucket for an element is decided by iteratee. Think of sorting a deck of cards into piles by suit and then reporting "13 hearts, 13 spades, …", except the rule for which pile a card belongs to is something you pass in. This mirrors Lodash's _.countBy: the iteratee can be a function you call on each element, or a property-name string as shorthand for "group by this field."

Signature

// collection: T[]              — the array to tally.
// iteratee:   ((el: T) => K)   — a function returning the bucket key, OR
//           | string           — a property name; shorthand for el => el[name].
// returns:    Record<string, number>
//   An object mapping each produced key (coerced to a string) to the
//   COUNT of elements that produced it.
function countBy(collection, iteratee): Record<string, number>;

Examples

// Function iteratee: bucket floats by their integer part.
countBy([6.1, 4.2, 6.3], Math.floor);
// → { '6': 2, '4': 1 }
// Function iteratee: split into even and odd piles.
countBy([1, 2, 3, 4, 5], (n) => (n % 2 === 0 ? 'even' : 'odd'));
// → { odd: 3, even: 2 }
// Property-name iteratee: group people by their city field.
const people = [
  { name: 'Ada', city: 'London' },
  { name: 'Linus', city: 'Helsinki' },
  { name: 'Grace', city: 'London' },
];
countBy(people, 'city');
// → { London: 2, Helsinki: 1 }

Notes

  • The iteratee has two forms. If it's a function, call it on each element to get the key. If it's a string, treat it as a property name — countBy(items, 'city') behaves like countBy(items, (x) => x.city).
  • Keys are object keys, so they become strings. A key of 6 and a key of '6' land in the same bucket; the returned object's keys are always strings.
  • The result counts, it doesn't collect. You return how many elements hit each key, not the elements themselves (that would be groupBy).
  • Empty in, empty out. countBy([], fn) returns {}.
  • Don't mutate the input. Read the collection; build a fresh result object.
  • Watch out for inherited keys. A plain {} already responds to result['toString'] and result['constructor'] — make sure a bucket named "toString" counts like any other key rather than colliding with an inherited method.
Loading editor…