indexBy
The indexBy utility indexes an array into an object keyed by a selector function. When multiple items share the same key, the last one wins.
Source Code
View Source Code
ts
import type { Primitive } from '../types';
import { assert } from '../function/assert';
import { IS_ARRAY_ERROR_MSG, isArray } from '../typed/isArray';
/**
* Creates an object keyed by selector result. Last item wins on collisions.
*/
export function indexBy<T>(array: T[], selector: (item: T) => Primitive): Record<string, T> {
assert(isArray(array), IS_ARRAY_ERROR_MSG, { args: { array }, type: TypeError });
const result: Record<string, T> = {};
for (const item of array) {
result[String(selector(item))] = item;
}
return result;
}Features
- Custom selector: Pass a function for computed keys.
- Last-wins deduplication: Duplicate keys overwrite earlier entries.
API
ts
function indexBy<T>(
array: T[],
selector: (item: T, index: number, array: T[]) => string | number | boolean,
): Record<string, T>;Parameters
array: The array to index.selector: A function(item: T, index: number, array: T[]) => string | number | booleanthat 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 Selector Function
ts
import { indexBy } from '@vielzeug/toolkit';
const users = [
{ id: 1, name: 'Alice' },
{ id: 2, name: 'Bob' },
{ id: 3, name: 'Charlie' },
];
indexBy(users, (user) => user.id);
// { '1': { id: 1, name: 'Alice' }, '2': { id: 2, name: 'Bob' }, '3': { id: 3, name: 'Charlie' } }Index with Selector Function
ts
import { indexBy } from '@vielzeug/toolkit';
const products = [
{ sku: 'A-1', name: 'Widget', price: 9.99 },
{ sku: 'B-2', name: 'Gadget', price: 19.99 },
];
const bySku = indexBy(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 { indexBy } from '@vielzeug/toolkit';
const data = [
{ a: 'x', v: 1 },
{ a: 'y', v: 2 },
{ a: 'x', v: 3 }, // overwrites first
];
indexBy(data, (item) => item.a);
// { x: { a: 'x', v: 3 }, y: { a: 'y', v: 2 } }