{"id":23789963,"url":"https://github.com/blackglory/structures","last_synced_at":"2026-02-23T05:34:06.013Z","repository":{"id":44964694,"uuid":"322842780","full_name":"BlackGlory/structures","owner":"BlackGlory","description":"🌳","archived":false,"fork":false,"pushed_at":"2024-09-23T20:07:50.000Z","size":2646,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-01-01T17:17:48.228Z","etag":null,"topics":["browser","esm","library","nodejs","npm-package","typescript"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@blackglory/structures","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/BlackGlory.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-12-19T12:28:24.000Z","updated_at":"2024-09-23T20:07:53.000Z","dependencies_parsed_at":"2024-04-17T07:44:29.729Z","dependency_job_id":"4bfed839-a320-4d69-8d2b-65acdd82be93","html_url":"https://github.com/BlackGlory/structures","commit_stats":{"total_commits":308,"total_committers":2,"mean_commits":154.0,"dds":"0.025974025974025983","last_synced_commit":"f2d7e8abd7cf3c37992a8ce34fc6525f07b980b3"},"previous_names":[],"tags_count":95,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fstructures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fstructures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fstructures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/BlackGlory%2Fstructures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/BlackGlory","download_url":"https://codeload.github.com/BlackGlory/structures/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":232333481,"owners_count":18507047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["browser","esm","library","nodejs","npm-package","typescript"],"created_at":"2025-01-01T17:17:50.058Z","updated_at":"2026-02-23T05:34:05.959Z","avatar_url":"https://github.com/BlackGlory.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# structures\nCommon structures.\n\n## Install\n```sh\nnpm install --save @blackglory/structures\n# or\nyarn add @blackglory/structures\n```\n\n## API\n### Box\n```ts\nclass Box\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n\n  constructor(value: T)\n\n  get(): T\n  set(value: T): void\n}\n```\n\n### Cons\n#### convertConsToArray\n```ts\nfunction convertConsToArray\u003cT\u003e([value, next]: Cons\u003cT\u003e): T[]\n```\n\n#### convertArrayToCons\n```ts\nfunction convertArrayToCons\u003cT\u003e([value, ...next]: T[]): Cons\u003cT\u003e\n```\n\n### Array\n#### sliceArrayLeft\n```ts\nfunction sliceArrayLeft\u003cT\u003e(arr: readonly T[], num: number): T[]\n```\n\n#### sliceArrayRight\n```ts\nfunction sliceArrayRight\u003cT\u003e(arr: readonly T[], num: number): T[]\n```\n\n#### truncateArrayLeft\n```ts\nfunction truncateArrayLeft(arr: unknown[], num: number): void\n```\n\n#### truncateArrayRight\n```ts\nfunction truncateArrayRight(arr: unknown[], num: number): void\n```\n\n#### clearArray\n```ts\nfunction clearArray(arr: unknown[]): void\n```\n\n### Emitter\n```ts\ntype Listener\u003cArgs extends unknown[]\u003e = (...args: Args) =\u003e void\n\nclass Emitter\u003c\n  EventToArgs extends Record\u003cEvent, unknown[]\u003e = Record\u003c\n    string | number | symbol\n  , unknown[]\n  \u003e\n, Event extends string | number | symbol = keyof EventToArgs\n\u003e {\n  get [Symbol.toStringTag](): string\n\n  on\u003cT extends Event\u003e(event: T, listener: Listener\u003cEventToArgs[T]\u003e): () =\u003e void\n  once\u003cT extends Event\u003e(event: T, listener: Listener\u003cEventToArgs[T]\u003e): () =\u003e void\n  emit\u003cT extends Event\u003e(event: T, ...args: EventToArgs[T]): void\n  removeAllListeners\u003cT extends Event\u003e(event: T): void\n}\n```\n\n### GeneratorEmitter\n```ts\ntype Listener\u003cArgs extends unknown[], Yield, Next\u003e = (...args: Args) =\u003e\n| void\n| Generator\u003cYield, void, Next\u003e\n\nclass GeneratorEmitter\u003c\n  EventToArgs extends Record\u003cEvent, unknown[]\u003e = Record\u003c\n    string | number | symbol\n  , unknown[]\n  \u003e\n, Event extends string | number | symbol = keyof EventToArgs\n, Yield = unknown\n, Next = unknown\n\u003e {\n  get [Symbol.toStringTag](): string\n\n  on\u003cT extends Event\u003e(\n    event: T\n  , listener: Listener\u003cEventToArgs[T], Yield, Next\u003e\n  ): () =\u003e void\n\n  once\u003cT extends Event\u003e(\n    event: T\n  , listener: Listener\u003cEventToArgs[T], Yield, Next\u003e\n  ): () =\u003e void\n\n  emit\u003cT extends Event\u003e(\n    event: T\n  , ...args: EventToArgs[T]\n  ): Generator\u003cYield, void, Next\u003e\n\n  removeAllListeners\u003cT extends Event\u003e(event: T): void\n}\n```\n\n### AsyncGeneratorEmitter\n```ts\ntype Listener\u003cArgs extends unknown[], Yield, Next\u003e = (...args: Args) =\u003e\n| void\n| Generator\u003cYield, void, Next\u003e\n| AsyncGenerator\u003cYield, void, Next\u003e\n\nclass AsyncGeneratorEmitter\u003c\n  EventToArgs extends Record\u003cEvent, unknown[]\u003e = Record\u003c\n    string | number | symbol\n  , unknown[]\n  \u003e\n, Event extends string | number | symbol = keyof EventToArgs\n, Yield = unknown\n, Next = unknown\n\u003e {\n  get [Symbol.toStringTag](): string\n\n  on\u003cT extends Event\u003e(event: T\n  , listener: Listener\u003cEventToArgs[T], Yield, Next\u003e\n  ): () =\u003e void\n\n  once\u003cT extends Event\u003e(\n    event: T\n  , listener: Listener\u003cEventToArgs[T], Yield, Next\u003e\n  ): () =\u003e void\n\n  emit\u003cT extends Event\u003e(\n    event: T\n  , ...args: EventToArgs[T]\n  ): AsyncGenerator\u003cYield, void, Next\u003e\n\n  removeAllListeners\u003cT extends Event\u003e(event: T): void\n}\n```\n\n### BigMap\n```ts\nclass BigMap\u003cK, V\u003e implements Iterable\u003c[K, V]\u003e {\n  get [Symbol.toStringTag](): string\n\n  get size(): number\n\n  set(key: K, value: V): void\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n  clear(): void\n\n  entries(): IterableIterator\u003c[K, V]\u003e\n  keys(): IterableIterator\u003cK\u003e\n  values(): IterableIterator\u003cV\u003e\n}\n```\n\nThe `Map` that supports unlimited elements.\n\nNote that `BigMap` cannot preserve the insertion order of elements.\n\n```ts\n// Map\nconst map = new Map()\nfor (let i = 0; i \u003c 100_000_000; i++) {\n  map.set(i, null) // RangeError\n}\nconsole.log('Never')\n\n// BigMap\nconst { BigMap } = require('.')\nconst map = new BigMap()\nfor (let i = 0; i \u003c 100_000_000; i++) {\n  map.set(i, null)\n}\nconsole.log('Done')\n```\n\n### BigSet\n```ts\nclass BigSet\u003cT\u003e implements Iterable\u003cT\u003e {\n  get [Symbol.toStringTag]: string\n\n  get size(): number\n\n  add(value: T): this\n  has(value: T): boolean\n  delete(value: T): boolean\n  clear(): void\n\n  values(): IterableIterator\u003cT\u003e\n}\n```\n\nThe `Set` that supports unlimited elements.\n\nNote that `BigSet` cannot preserve the insertion order of elements.\n\n```ts\n// Set\nconst set = new Set()\nfor (let i = 0; i \u003c 100_000_000; i++) {\n  set.add(i) // RangeError\n}\nconsole.log('Never')\n\n// BigSet\nconst set = new BigSet()\nfor (let i = 0; i \u003c 100_000_000; i++) {\n  set.add(i)\n}\nconsole.log('Done')\n```\n\n### HashMap\n```ts\nclass HashMap\u003cK, V, Hash = unknown\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n\n  constructor(hash: (key: K) =\u003e Hash)\n\n  set(key: K, value: V): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n  clear(): void\n}\n```\n\n### HashSet\n```ts\nclass HashSet\u003cV, Hash = unknown\u003e implements Iterable\u003cV\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n  [Symbol.iterator](): IterableIterator\u003cV\u003e\n\n  constructor(hash: (value: V) =\u003e Hash)\n\n  add(value: V): this\n  delete(value: V): boolean\n  has(value: V): boolean\n  get(value: V): V | undefined\n  clear(): void\n  keys(): IterableIterator\u003cV\u003e\n  values(): IterableIterator\u003cV\u003e\n}\n```\n\n### LRUMap\n```ts\nclass LRUMap\u003cK, V\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n\n  constructor(limit: number)\n\n  set(key: K, value: V): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n  clear(): void\n}\n```\n\n### ExpirableMap\n```ts\nclass ExpirableMap\u003cK, V\u003e {\n  get[Symbol.toStringTag](): string\n  get size(): number\n\n  constructor()\n\n  set(key: K, value: V, timeToLive?: number = Infinity): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n  clear(): void\n}\n```\n\n### TLRUMap\n```ts\nclass TLRUMap\u003cK, V\u003e {\n  get[Symbol.toStringTag](): string\n  get size(): number\n\n  constructor(limit: number)\n\n  set(key: K, value: V, timeToLive?: number = Infinity): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n  clear(): void\n}\n```\n\n### Queue\n```ts\nclass Queue\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n\n  empty(): void\n  enqueue(...items: T[]): void\n  dequeue(): T | undefined\n  remove(item: T): void\n}\n```\n\n### TrieMap\n```ts\nclass TrieMap\u003cK extends Iterable\u003cT\u003e, V, T = unknown\u003e {\n  get [Symbol.toStringTag](): string\n\n  keys(): IterableIterator\u003cT[]\u003e\n  values(): IterableIterator\u003cV\u003e\n  entries(): IterableIterator\u003c[key: T[], value: V]\u003e\n\n  set(key: K, value: V): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n}\n```\n\nNote that you might expect this data structure to be more space efficient than `BigMap`, but it doesn't.\nIn V8, it can only store about 80% of data of `BigMap`.\n\n### StringTrieMap\n```ts\nclass StringTrieMap\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n\n  keys(): IterableIterator\u003cstring\u003e\n  values(): IterableIterator\u003cT\u003e\n  entries(): IterableIterator\u003c[key: string, value: T]\u003e\n\n  set(key: string, value: T): this\n  has(key: string): boolean\n  get(key: string): T | undefined\n  delete(key: string): boolean\n}\n```\n\nNote that you might expect this data structure to be more space efficient than `BigMap`, but it doesn't.\nIn V8, it can only store about 80% of data of `BigMap`.\n\n### RadixTree\n```ts\nclass RadixTree\u003cK extends Iterable\u003cT\u003e, V, T = unknown\u003e {\n  get [Symbol.toStringTag](): string\n\n  entries(): IterableIterator\u003c[key: T[], value: V]\u003e\n  keys(): IterableIterator\u003cT[]\u003e\n  values(): IterableIterator\u003cV\u003e\n\n  set(key: K, value: V): this\n  has(key: K): boolean\n  get(key: K): V | undefined\n  delete(key: K): boolean\n}\n```\n\nNote that you might expect this data structure to be more space efficient than `BigMap`, but it doesn't.\nIn V8, it can only store about 80% of data of `BigMap`.\n\n### StringRadixTree\n```ts\nclass StringRadixTree\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n\n  keys(): IterableIterator\u003cstring\u003e\n  values(): IterableIterator\u003cT\u003e\n  entries(): IterableIterator\u003c[key: string, value: T]\u003e\n\n  set(key: string, value: T): this\n  has(key: string): boolean\n  get(key: string): T | undefined\n  delete(key: string): boolean\n}\n```\n\nNote that you might expect this data structure to be more space efficient than `BigMap`, but it doesn't.\nIn V8, it can only store about 80% of data of `BigMap`.\n\n### SparseSet\n```ts\nclass SparseSet implements Iterable\u003cnumber\u003e {\n  get [Symbol.toStringTag](): string\n  get [Symbol.iterator](): IterableIterator\u003cnumber\u003e\n  get size(): number\n\n  constructor(array?: number[])\n\n  values(): IterableIterator\u003cnumber\u003e\n\n  has(value: number): boolean\n  add(value: number): void\n  delete(value: number): boolean\n  clear(): void\n\n  clone(): SparseSet\n}\n```\n\n### SparseMap\n```ts\nclass SparseMap\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n\n  /**\n   * `SparseMap` cannot respond to any operations on the internal array,\n   * you must ensure that indexes accessed are less than the length of `SparseMap`.\n   * \n   * Keys do not correspond to indexes of the array.\n   */\n  get internalArray(): T[]\n\n  entries(): IterableIterator\u003c[key: number, value: T]\u003e\n  keys(): IterableIterator\u003cnumber\u003e\n  values(): IterableIterator\u003cT\u003e\n\n  getInternalIndexOfKey(key: number): number | undefined\n\n  has(key: number): boolean\n  get(key: number): T | undefined\n  set(key: number, value: T): void\n  delete(key: number): void\n  clear(): void\n}\n```\n\n### DynamicTypedArray\n```ts\nclass DynamicTypedArray\u003cT extends TypedArrayConstructor\u003e {\n  get [Symbol.toStringTag](): string\n  get BYTES_PER_ELEMENT(): number\n  get capacity(): number\n  get length(): number\n  readonly growthFactor: number\n\n  /**\n   * `DynamicTypedArray` cannot respond to any operations on the internal array,\n   * you must ensure that indexes accessed are less than the length of `DynamicTypedArray`.\n   */\n  get internalTypedArray(): TypedArrayOfConstructor\u003cT\u003e\n\n  constructor(\n    typedArrayConstructor: T\n  , options?: {\n      capacity?: number = 0\n      growthFactor?: number = 1.5\n    }\n  )\n\n  set(index: number, value: number): void\n  setValues(index: number, values: TypedArrayOfConstructor\u003cT\u003e): void\n  get(index: number): number | undefined\n  push(...values: number[]): void\n  pop(): number | undefined\n  clear(): void\n  sort(compare?: (a: number, b: number) =\u003e number): void\n}\n```\n\n### TypedSparseSet\n```ts\nclass TypedSparseSet\u003cT extends UnsignedTypedArrayConstructor\u003e {\n  get [Symbol.toStringTag](): string\n  get [Symbol.iterator](): IterableIterator\u003cnumber\u003e\n  get size(): number\n\n  constructor(array: DynamicTypedArray\u003cT\u003e)\n\n  values(): IterableIterator\u003cnumber\u003e\n\n  has(value: number): boolean\n  add(value: number): void\n  delete(value: number): boolean\n  clear(): void\n}\n```\n\n### TypedSparseMap\n```ts\nclass TypedSparseMap\u003cT extends TypedArrayConstructor\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n\n  /**\n   * `SparseMap` cannot respond to any operations on the internal array,\n   * you must ensure that indexes accessed are less than the length of `SparseMap`.\n   * \n   * Keys do not correspond to indexes of the array.\n   */\n  get internalTypedArray(): TypedArrayOfConstructor\u003cT\u003e\n\n  constructor(array: DynamicTypedArray\u003cT\u003e)\n\n  entries(): IterableIterator\u003c[key: number, value: number]\u003e\n  keys(): IterableIterator\u003cnumber\u003e\n  values(): IterableIterator\u003cnumber\u003e\n\n  getInternalIndexOfKey(key: number): number | undefined\n\n  has(key: number): boolean\n  get(key: number): T | undefined\n  set(key: number, value: number): void\n  delete(key: number): void\n  clear(): void\n}\n```\n\n### SortedSet\n```ts\nclass SortedSet\u003cT\u003e {\n  get [Symbol.toStringTag](): string\n  [Symbol.iterator](): IterableIterator\u003cT\u003e\n\n  constructor(compare: (a: T, b: T) =\u003e number)\n\n  values(): IterableIterator\u003cT\u003e\n  has(value: T): boolean\n  add(value: T): void\n  delete(value: T): void\n}\n```\n\n### BitSet\n```ts\nclass BitSet {\n  get [Symbol.toStringTag](): string\n  get size(): number\n  [Symbol.iterator](): IterableIterator\u003cnumber\u003e\n\n  constructor(bitsPerElement: number = 8)\n\n  values(): IterableIterator\u003cnumber\u003e\n\n  has(value: number): boolean\n  add(value: number): boolean\n  delete(value: number): boolean\n  clear(): void\n\n  clone(): BitSet\n}\n```\n\nDue to the length of arrays supported by JavaScript,\n`BitSet` cannot support very large values.\n\n### TypedBitSet\n```ts\nclass TypedBitSet\u003cT extends UnsignedTypedArrayConstructor\u003e {\n  get [Symbol.toStringTag](): string\n  get size(): number\n  [Symbol.iterator](): IterableIterator\u003cnumber\u003e\n\n  constructor(array: DynamicTypedArray\u003cT\u003e)\n\n  values(): IterableIterator\u003cnumber\u003e\n\n  has(value: number): boolean\n  add(value: number): boolean\n  delete(value: number): boolean\n  clear(): void\n}\n```\n\nDue to the length of arrays supported by JavaScript,\n`TypedBitSit` cannot support very large values.\n\n### DisjointSet\n```ts\nclass DisjointSet {\n  has(value: number): boolean\n  sets(): number[][]\n\n  makeSet(value: number): number\n  union(a: number, b: number): void\n  find(value: number): number\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackglory%2Fstructures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fblackglory%2Fstructures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fblackglory%2Fstructures/lists"}