UNPKG

indexed-collection

Version:

A zero-dependency library of classes that make filtering, sorting and observing changes to arrays easier and more efficient.

64 lines (57 loc) 2.08 kB
import { ICollectionOption } from '../core/ICollectionOption'; import { IIndex } from '../core/IIndex'; import { SingleKeyExtract } from '../core/KeyExtract'; import { Optional } from '../core/Optional'; import { defaultCollectionOption } from '../core/defaultCollectionOption'; import { CollectionIndex } from '../indexes/CollectionIndex'; import { IndexedCollectionBase } from './IndexedCollectionBase'; /** * A collection where every item contains a unique identifier key (aka primary key) */ export class PrimaryKeyCollection<T, IdT = string> extends IndexedCollectionBase<T> { protected readonly idIndex: CollectionIndex<T, [IdT]>; constructor( public readonly primaryKeyExtract: SingleKeyExtract<T, IdT>, initialValues?: readonly T[], additionalIndexes: ReadonlyArray<IIndex<T>> = [], option: Readonly<ICollectionOption> = defaultCollectionOption ) { super(undefined, undefined, option); this.idIndex = new CollectionIndex<T, [IdT]>([primaryKeyExtract]); this.buildIndexes([this.idIndex, ...additionalIndexes]); if (initialValues) { this.addRange(initialValues); } } protected override buildIndexes(indexes: readonly IIndex<T>[], autoReindex?: boolean): void { const combinedIndex: IIndex<T>[] = []; if (this.idIndex != null) { // this.idIndex can be null during instantiation combinedIndex.push(this.idIndex); } if (indexes != null && indexes.length > 0) { combinedIndex.push(...indexes); } super.buildIndexes(combinedIndex, autoReindex); } exists(item: T): boolean { const key = this.primaryKeyExtract(item); return Boolean(this.byPrimaryKey(key)); } /** * Get the item by its primary key * @param keyValue * @returns */ byPrimaryKey(keyValue: IdT): Optional<T> { return this.idIndex.getValue(keyValue)[0]; } override update(newItem: T): boolean { const key = this.primaryKeyExtract(newItem); const oldItem = this.byPrimaryKey(key); if (oldItem) { return super.update(newItem, oldItem); } return false; } }