Skip to content

Instantly share code, notes, and snippets.

@dmorosinotto
Last active November 16, 2023 13:14
Show Gist options
  • Save dmorosinotto/1aaf6821884a771e30dfc4793b46342f to your computer and use it in GitHub Desktop.
Save dmorosinotto/1aaf6821884a771e30dfc4793b46342f to your computer and use it in GitHub Desktop.
Generic indexBy function + toDictionary RxJS Operator
import { type Observable } from 'rxjs';
import { map } from "rxjs/operators";
//GENERIC toDictionary OPERATOR + indexBy FUNCTION RETURN Map<indexOf, item> TO OTTIMIZE O(1) EXIST/RETRIVE OF ITEM BY idxOf (.has(idx)/.get(idx))
export type Indexer<T extends {}> = keyof T | ((item: T) => unknown);
export type IndexOf<T, I extends Indexer<T>> = I extends keyof T ? T[I] : I extends (...args: any) => any ? ReturnType<I> : never;
export const indexBy = <T, I extends Indexer<T>>(array: T[], keyOrIndexer: I): Map<IndexOf<T, I>, T> => {
if (!array) return new Map<IndexOf<T, I>, T>();
const idexerFn: (item: T) => IndexOf<T, I> = (
typeof keyOrIndexer === "function" ? keyOrIndexer : (item: T) => item[keyOrIndexer as keyof T]
) as any;
return new Map(array.map((item) => [idexerFn(item), item]));
};
export const toDictionary = <T, I extends Indexer<T>>(keyOrIndexer: I) => map((array: T[]) => indexBy(array, keyOrIndexer));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment