diff --git a/packages/core/src/common/utils/iter.ts b/packages/core/src/common/utils/iter.ts index dc1c4621fd..b27595de94 100644 --- a/packages/core/src/common/utils/iter.ts +++ b/packages/core/src/common/utils/iter.ts @@ -14,6 +14,7 @@ interface Iterator extends Iterable { flatMap(fn: (val: T) => U[]): Iterator; concat(src2: IterableIterator): Iterator; join(sep?: string): string; + count(): T extends string ? { [P in T]?: number; } : never; } export function chain(src: IterableIterator): Iterator { @@ -26,6 +27,7 @@ export function chain(src: IterableIterator): Iterator { join: (sep) => join(src, sep), collect: (fn) => fn(src), concat: (src2) => chain(concat(src, src2)), + count: () => countBy(src as unknown as Iterable) as any, [Symbol.iterator]: () => src, }; } @@ -246,3 +248,15 @@ export function* concat(...sources: IterableIterator[]): IterableIterator< } } } + +export function countBy(src: Iterable): Partial> { + const result: Partial> = {}; + + for (const item of src) { + result[item] ??= 0; + // eslint-disable-next-line @typescript-eslint/no-non-null-assertion + result[item]! += 1; + } + + return result; +}