keyBy()
keyBy<
T,K>(array,iteratee):Partial<Record<K,T>>
Creates an object composed of keys generated from the results of running each element through iteratee.
In case of duplicate keys, the last value wins.
Type Parametersβ
T: Tβ
The type of elements in the array.
K: K extends PropertyKeyβ
The type of the key returned by the iteratee.
Parametersβ
array: readonly T[]β
The array to iterate over.
iteratee: (value) => Kβ
A function that returns the key for each element.
Returns: Partial<Record<K, T>>β
An object with keys mapping to elements.
Sinceβ
2.0.0
Performanceβ
O(n) time & space.
Also known asβ
indexBy (Remeda, Ramda) Β· keyBy (Lodash, es-toolkit) Β· objectify (Radashi) Β· β (Effect, Modern Dash, Antfu)
Exampleβ
const users = [
{ id: 1, name: 'John' },
{ id: 2, name: 'Jane' },
{ id: 3, name: 'Bob' }
];
keyBy(users, (u) => u.id);
// => { 1: { id: 1, name: 'John' }, 2: { id: 2, name: 'Jane' }, 3: { id: 3, name: 'Bob' } }
keyBy(['apple', 'banana', 'cherry'], (s) => s[0]);
// => { a: 'apple', b: 'banana', c: 'cherry' }
How it works?β
Creates an object where each element is stored under a computed key. Last value wins for duplicate keys.
keyBy vs groupByβ
| Function | Duplicate keys | Returns |
|---|---|---|
keyBy | Last wins | { key: T } |
groupBy | All kept | { key: T[] } |
Use Casesβ
Create lookup tables for instant access by ID πβ
Transform an array into an object indexed by unique identifier. Perfect for normalizing API responses, caching entities, or quick O(1) lookups.
const users = [
{ id: "u1", name: "Alice", role: "admin" },
{ id: "u2", name: "Bob", role: "user" },
{ id: "u3", name: "Charlie", role: "user" },
];
const usersById = keyBy(users, (u) => u.id);
// => {
// u1: { id: "u1", name: "Alice", role: "admin" },
// u2: { id: "u2", name: "Bob", role: "user" },
// u3: { id: "u3", name: "Charlie", role: "user" }
// }
const alice = usersById["u1"];
// => { id: "u1", name: "Alice", role: "admin" }
Index configuration objects by key property πβ
Map settings or config items for quick retrieval by name or code. Ideal for feature flags, locale settings, or environment configurations.
const features = [
{ code: "DARK_MODE", enabled: true, description: "Enable dark theme" },
{ code: "BETA_UI", enabled: false, description: "New UI experiment" },
{ code: "ANALYTICS", enabled: true, description: "Track user events" },
];
const featureFlags = keyBy(features, (f) => f.code);
// => {
// DARK_MODE: { code: "DARK_MODE", enabled: true, ... },
// BETA_UI: { code: "BETA_UI", enabled: false, ... },
// ANALYTICS: { code: "ANALYTICS", enabled: true, ... }
// }
if (featureFlags["DARK_MODE"]?.enabled) {
applyDarkTheme();
}
Map relational data for join-like operationsβ
Index related entities to efficiently merge data from multiple sources. Useful for combining API responses, denormalizing data, or building relationships.
const orders = [
{ orderId: 1, productId: "p1", quantity: 2 },
{ orderId: 2, productId: "p3", quantity: 1 },
{ orderId: 3, productId: "p2", quantity: 5 },
];
const products = [
{ sku: "p1", name: "Keyboard", price: 79 },
{ sku: "p2", name: "Mouse", price: 29 },
{ sku: "p3", name: "Monitor", price: 299 },
];
const productsBySku = keyBy(products, (p) => p.sku);
const enrichedOrders = orders.map((order) => ({
...order,
product: productsBySku[order.productId],
total: (productsBySku[order.productId]?.price ?? 0) * order.quantity,
}));
Normalize API response for a Redux/Zustand store πβ
Convert an array of entities into a normalized { byId, allIds } structure for state management.
The most common real-world pattern for keyBy in any app using Redux, Zustand, or similar stores.
const apiResponse = [
{ id: "p1", title: "Build UI", status: "done" },
{ id: "p2", title: "Write tests", status: "in-progress" },
{ id: "p3", title: "Deploy", status: "todo" },
];
const normalized = {
byId: keyBy(apiResponse, (item) => item.id),
allIds: apiResponse.map((item) => item.id),
};
// normalized.byId["p2"] => { id: "p2", title: "Write tests", status: "in-progress" }
// normalized.allIds => ["p1", "p2", "p3"]
// Fast update without scanning the array
normalized.byId["p2"] = { ...normalized.byId["p2"], status: "done" };
Index i18n translations by key for fast lookupβ
Build a translation dictionary from an array of key-value pairs. Essential for i18n systems loading translations from APIs or JSON files.
const translationEntries = [
{ key: "btn.save", value: "Sauvegarder" },
{ key: "btn.cancel", value: "Annuler" },
{ key: "msg.welcome", value: "Bienvenue" },
{ key: "msg.goodbye", value: "Au revoir" },
];
const translations = keyBy(translationEntries, (t) => t.key);
const t = (key: string) => translations[key]?.value ?? key;
t("btn.save"); // => "Sauvegarder"
t("btn.unknown"); // => "btn.unknown" (fallback to key)