| type Key = string | number | symbol; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| export class SetArray<T extends Key = Key> { |
| declare private _indexes: Record<T, number | undefined>; |
| declare array: readonly T[]; |
|
|
| constructor() { |
| this._indexes = { __proto__: null } as any; |
| this.array = []; |
| } |
| } |
|
|
| interface PublicSet<T extends Key> { |
| array: T[]; |
| _indexes: SetArray<T>['_indexes']; |
| } |
|
|
| |
| |
| |
| |
| function cast<T extends Key>(set: SetArray<T>): PublicSet<T> { |
| return set as any; |
| } |
|
|
| |
| |
| |
| export function get<T extends Key>(setarr: SetArray<T>, key: T): number | undefined { |
| return cast(setarr)._indexes[key]; |
| } |
|
|
| |
| |
| |
| |
| export function put<T extends Key>(setarr: SetArray<T>, key: T): number { |
| |
| const index = get(setarr, key); |
| if (index !== undefined) return index; |
|
|
| const { array, _indexes: indexes } = cast(setarr); |
|
|
| const length = array.push(key); |
| return (indexes[key] = length - 1); |
| } |
|
|
| |
| |
| |
| export function pop<T extends Key>(setarr: SetArray<T>): void { |
| const { array, _indexes: indexes } = cast(setarr); |
| if (array.length === 0) return; |
|
|
| const last = array.pop()!; |
| indexes[last] = undefined; |
| } |
|
|
| |
| |
| |
| export function remove<T extends Key>(setarr: SetArray<T>, key: T): void { |
| const index = get(setarr, key); |
| if (index === undefined) return; |
|
|
| const { array, _indexes: indexes } = cast(setarr); |
| for (let i = index + 1; i < array.length; i++) { |
| const k = array[i]; |
| array[i - 1] = k; |
| indexes[k]!--; |
| } |
| indexes[key] = undefined; |
| array.pop(); |
| } |
|
|