48 lines
1.2 KiB
TypeScript
48 lines
1.2 KiB
TypeScript
|
export interface Identifiable {
|
||
|
id?: string;
|
||
|
}
|
||
|
|
||
|
function normalize<T extends Identifiable>(
|
||
|
values: T[],
|
||
|
idOrIndex: string | number
|
||
|
): number {
|
||
|
const normalizedIndex =
|
||
|
typeof idOrIndex === "string"
|
||
|
? values.findIndex((value) => value.id === idOrIndex)
|
||
|
: idOrIndex >= 0
|
||
|
? idOrIndex
|
||
|
: values.length + idOrIndex;
|
||
|
|
||
|
return normalizedIndex >= values.length ? -1 : normalizedIndex;
|
||
|
}
|
||
|
|
||
|
export function search<T extends Identifiable>(
|
||
|
values: T[],
|
||
|
idOrIndex: string | number
|
||
|
): T | null {
|
||
|
const index = normalize(values, idOrIndex);
|
||
|
return index >= 0 ? values[index] : null;
|
||
|
}
|
||
|
|
||
|
export function insert<T extends Identifiable>(
|
||
|
values: T[],
|
||
|
value: T,
|
||
|
idOrIndex: string | number
|
||
|
): T[] {
|
||
|
const index = normalize(values, idOrIndex);
|
||
|
return index >= 0
|
||
|
? [...values.slice(0, index), value, ...values.slice(index)]
|
||
|
: values;
|
||
|
}
|
||
|
|
||
|
export function add<T extends Identifiable>(
|
||
|
values: T[],
|
||
|
value: T,
|
||
|
idOrIndex: string | number
|
||
|
): T[] {
|
||
|
const index = normalize(values, idOrIndex);
|
||
|
return index >= 0
|
||
|
? [...values.slice(0, index + 1), value, ...values.slice(index + 1)]
|
||
|
: values;
|
||
|
}
|