keyBy
The keyBy utility indexes an array into an object keyed by a property or selector function. When multiple items share the same key, the last one wins.
Source Code
View Source Code
ts
import type { Selector } from '../types';
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
/**
* Creates an object keyed by a property or selector function. When multiple
* items share the same key, the last one wins.
*
* @example
* ```ts
* const data = [{ a: 'x', v: 1 }, { a: 'y', v: 2 }, { a: 'x', v: 3 }];
* keyBy(data, 'a') // { x: { a: 'x', v: 3 }, y: { a: 'y', v: 2 } }
* keyBy(data, item => item.a) // same result
* ```
*
* @param array - The array to index.
* @param selector - A property key or a function returning the key for each element.
* @returns A record mapping each key to the corresponding element.
*
* @throws {TypeError} If the provided array is not an array.
*/
export function keyBy<T>(array: T[], selector: Selector<T>): Record<string, T> {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
const result: Record<string, T> = {};
const getKey = typeof selector === 'function' ? selector : (item: T) => item[selector];
for (const item of array) {
const key = String(getKey(item));
result[key] = item;
}
return result;
}Features
- Property shorthand: Pass a string key for simple property-based indexing.
- Custom selector: Pass a function for computed keys.
- Last-wins deduplication: Duplicate keys overwrite earlier entries.
API
ts
function keyBy<T>(array: T[], selector: Selector<T>): Record<string, T>;Parameters
array: The array to index.selector: A property key string or a function(item: T) => string | numberthat returns the key for each element.
Returns
- A
Record<string, T>mapping each key to its corresponding element.
Throws
TypeError: If the first argument is not an array.
Examples
Index by Property Key
ts
import { keyBy } from '@vielzeug/toolkit';
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
];
keyBy(users, 'id');
// { '1': { id: 1, name: 'Alice' }, '2': { id: 2, name: 'Bob' }, '3': { id: 3, name: 'Charlie' } }Index with Selector Function
ts
import { keyBy } from '@vielzeug/toolkit';
const products = [
{ sku: 'A-1', name: 'Widget', price: 9.99 },
{ sku: 'B-2', name: 'Gadget', price: 19.99 },
];
const bySku = keyBy(products, (p) => p.sku);
// { 'A-1': { sku: 'A-1', ... }, 'B-2': { sku: 'B-2', ... } }
// Fast O(1) lookup
bySku['A-1'].name; // 'Widget'Duplicate Keys (Last Wins)
ts
import { keyBy } from '@vielzeug/toolkit';
const data = [
{ a: 'x', v: 1 },
{ a: 'y', v: 2 },
{ a: 'x', v: 3 }, // overwrites first
];
keyBy(data, 'a');
// { x: { a: 'x', v: 3 }, y: { a: 'y', v: 2 } }