2021-04-15 15:59:52 +02:00
|
|
|
// Copyright: Ankitects Pty Ltd and contributors
|
|
|
|
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
2021-04-09 00:51:20 +02:00
|
|
|
export interface Identifiable {
|
|
|
|
id?: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
function normalize<T extends Identifiable>(
|
|
|
|
values: T[],
|
|
|
|
idOrIndex: string | number
|
|
|
|
): number {
|
2021-04-23 18:21:03 +02:00
|
|
|
let normalizedIndex: number;
|
|
|
|
|
2021-04-23 05:00:18 +02:00
|
|
|
if (typeof idOrIndex === "string") {
|
2021-04-23 18:21:03 +02:00
|
|
|
normalizedIndex = values.findIndex((value) => value.id === idOrIndex);
|
2021-04-23 18:53:52 +02:00
|
|
|
} else if (idOrIndex < 0) {
|
2021-04-23 18:21:03 +02:00
|
|
|
normalizedIndex = values.length + idOrIndex;
|
2021-04-23 18:53:52 +02:00
|
|
|
} else {
|
2021-04-23 18:21:03 +02:00
|
|
|
normalizedIndex = idOrIndex;
|
|
|
|
}
|
|
|
|
|
|
|
|
return normalizedIndex >= values.length ? -1 : normalizedIndex;
|
2021-04-09 00:51:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
|
|
|
}
|