Key ByLoading saved progress…

Key By

Keying a collection turns a flat list into a lookup table: you derive a key for each element and store the element under that key, so you can later reach any element in one step instead of scanning the whole list. This is lodash's _.keyBy — the "index my list by id" helper you reach for right after fetching an array of records from an API.

Implement keyBy(collection, iteratee). Walk the collection, ask the iteratee for a key for each element, and build an object that maps each key to the element that produced it. When two elements produce the same key, the last one wins — it overwrites the earlier one.

Signature

type Iteratee<T> = ((value: T) => unknown) | string;

function keyBy<T>(
  collection: T[],
  iteratee: Iteratee<T>
): Record<string, T>;

The iteratee is either a function called with each element, or a string property name looked up on each element. Whatever it returns becomes the key (coerced to a string); the value stored under that key is the element itself.

Examples

// Function iteratee — index users by id
const users = [
  { id: 'a1', name: 'Ada' },
  { id: 'b2', name: 'Grace' },
];
keyBy(users, (u) => u.id);
// → { a1: { id: 'a1', name: 'Ada' }, b2: { id: 'b2', name: 'Grace' } }
// String shorthand + a key collision — the LAST row wins
const rows = [
  { id: 1, label: 'first' },
  { id: 1, label: 'second' },
];
keyBy(rows, 'id');
// → { '1': { id: 1, label: 'second' } }

Notes

  • One element per key — unlike grouping, each key maps to a single element, not an array. If two elements share a key, keep the later one.
  • String coercion — object keys are always strings, so a numeric key like 1 becomes the key '1'.
  • String iteratee — when iteratee is a string, treat it as a property name: the key is element[iteratee].
  • Empty inputkeyBy([], anything) returns {}.
  • The element, not a copy — store a reference to the original element; don't clone it.
Loading editor…