1
0
This commit is contained in:
Herve BECHER
2025-05-24 12:11:44 +02:00
parent e5e6bffe1e
commit 0fd0e3bada
24 changed files with 1702 additions and 688 deletions

View File

@@ -65,6 +65,37 @@ export class ToObjectCollector<TElement, TKey extends PropertyKey, TValue> imple
}
}
export class ToObjectListCollector<TElement, TKey extends PropertyKey, TValue> implements Collector<TElement, Record<TKey, TValue[]>, Record<TKey, TValue[]>> {
readonly #keySelector: Converter<TElement, TKey>;
readonly #valueSelector: Converter<TElement, TValue>;
constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
this.#keySelector = keySelector;
this.#valueSelector = valueSelector;
}
initialize() {
return {} as Record<TKey, TValue[]>;
}
accumulate(accumulator: Record<TKey, TValue[]>, element: TElement) {
const key = this.#keySelector(element);
const value = this.#valueSelector(element);
const l = accumulator[key];
if (l) {
l.push(value);
} else {
accumulator[key] = [value];
}
}
finalize(accumulator: Record<TKey, TValue[]>) {
return accumulator;
}
}
export class ToMapCollector<TElement, TKey, TValue> implements Collector<TElement, Map<TKey, TValue>, Map<TKey, TValue>> {
readonly #keySelector: Converter<TElement, TKey>;
readonly #valueSelector: Converter<TElement, TValue>;
@@ -90,6 +121,37 @@ export class ToMapCollector<TElement, TKey, TValue> implements Collector<TElemen
}
}
export class ToMapListCollector<TElement, TKey, TValue> implements Collector<TElement, Map<TKey, TValue[]>, Map<TKey, TValue[]>> {
readonly #keySelector: Converter<TElement, TKey>;
readonly #valueSelector: Converter<TElement, TValue>;
constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
this.#keySelector = keySelector;
this.#valueSelector = valueSelector;
}
initialize() {
return new Map<TKey, TValue[]>();
}
accumulate(accumulator: Map<TKey, TValue[]>, element: TElement) {
const key = this.#keySelector(element);
const value = this.#valueSelector(element);
const l = accumulator.get(key);
if (l) {
l.push(value);
} else {
accumulator.set(key, [value]);
}
}
finalize(accumulator: Map<TKey, TValue[]>) {
return accumulator;
}
}
export class ToSetCollector<TElement> implements Collector<TElement, Set<TElement>, Set<TElement>> {
initialize() {
return new Set<TElement>();
@@ -128,60 +190,60 @@ export class JoinCollector implements Collector<any, any[], string> {
}
}
export class SumCollector implements Collector<number, { sum: number }, number> {
export class SumCollector implements Collector<number, { sum: number; }, number> {
initialize() {
return { sum: 0 };
}
accumulate(accumulator: { sum: number }, element: number) {
accumulate(accumulator: { sum: number; }, element: number) {
accumulator.sum += element;
}
finalize(accumulator: { sum: number }) {
finalize(accumulator: { sum: number; }) {
return accumulator.sum;
}
}
export class BigIntSumCollector implements Collector<bigint, { sum: bigint }, bigint> {
export class BigIntSumCollector implements Collector<bigint, { sum: bigint; }, bigint> {
initialize() {
return { sum: 0n, };
}
accumulate(accumulator: { sum: bigint }, element: bigint) {
accumulate(accumulator: { sum: bigint; }, element: bigint) {
accumulator.sum += element;
}
finalize(accumulator: { sum: bigint }) {
finalize(accumulator: { sum: bigint; }) {
return accumulator.sum;
}
}
export class AverageCollector implements Collector<number, { count: number, sum: number }, number> {
export class AverageCollector implements Collector<number, { count: number, sum: number; }, number> {
initialize() {
return { count: 0, sum: 0 };
}
accumulate(accumulator: { count: number, sum: number }, element: number) {
accumulate(accumulator: { count: number, sum: number; }, element: number) {
accumulator.count++;
accumulator.sum += element;
}
finalize(accumulator: { count: number, sum: number }) {
finalize(accumulator: { count: number, sum: number; }) {
return accumulator.count === 0 ? 0 : accumulator.sum / accumulator.count;
}
}
export class BigIntAverageCollector implements Collector<bigint, { count: number, sum: bigint }, bigint> {
export class BigIntAverageCollector implements Collector<bigint, { count: number, sum: bigint; }, bigint> {
initialize() {
return { count: 0, sum: 0n };
}
accumulate(accumulator: { count: number, sum: bigint }, element: bigint) {
accumulate(accumulator: { count: number, sum: bigint; }, element: bigint) {
accumulator.count++;
accumulator.sum += element;
}
finalize(accumulator: { count: number, sum: bigint }) {
finalize(accumulator: { count: number, sum: bigint; }) {
return accumulator.count === 0 ? 0n : accumulator.sum / BigInt(accumulator.count);
}
}

View File

@@ -1,5 +1,5 @@
import { Converter } from "../types.js";
import { SimpleCollector, ToArrayCollector, ToObjectCollector, ToMapCollector, ToSetCollector, JoinCollector, SumCollector, BigIntSumCollector, AverageCollector, BigIntAverageCollector } from "./impl.js";
import { SimpleCollector, ToArrayCollector, ToObjectCollector, ToMapCollector, ToSetCollector, JoinCollector, SumCollector, BigIntSumCollector, AverageCollector, BigIntAverageCollector, ToObjectListCollector, ToMapListCollector } from "./impl.js";
import { Collector } from "./types.js";
export function create<TElement, TAccumulator, TResult>(initialize: () => TAccumulator, accumulate: (accumulator: TAccumulator, element: TElement) => void,
@@ -17,10 +17,18 @@ export function toObject<TElement, TKey extends PropertyKey, TValue>(keySelector
return new ToObjectCollector<TElement, TKey, TValue>(keySelector, valueSelector);
}
export function toObjectList<TElement, TKey extends PropertyKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Record<TKey, TValue[]>> {
return new ToObjectListCollector<TElement, TKey, TValue>(keySelector, valueSelector);
}
export function toMap<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Map<TKey, TValue>> {
return new ToMapCollector<TElement, TKey, TValue>(keySelector, valueSelector);
}
export function toMapList<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Map<TKey, TValue[]>> {
return new ToMapListCollector<TElement, TKey, TValue>(keySelector, valueSelector);
}
const toSetCollector = new ToSetCollector<any>();
export function toSet<TElement>(): Collector<TElement, any, Set<TElement>> {

219
src/collector/v2/impl.ts Normal file
View File

@@ -0,0 +1,219 @@
// import { Converter } from "../../types.js";
// import { CollectorFactory, CollectorInstance } from "./types.js";
// export class ToArrayCollectorFactory<TElement> implements CollectorFactory<TElement, TElement[]> {
// initialize() {
// return new ToArrayCollectorInstance<TElement>();
// }
// };
// class ToArrayCollectorInstance<TElement> implements CollectorInstance<TElement, TElement[]> {
// readonly #accumulator: TElement[];
// constructor() {
// this.#accumulator = [];
// }
// accumulate(element: TElement) {
// this.#accumulator.push(element);
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class ToObjectCollectorFactory<TElement, TKey extends PropertyKey, TValue> implements CollectorFactory<TElement, Record<TKey, TValue>> {
// readonly #keySelector: Converter<TElement, TKey>;
// readonly #valueSelector: Converter<TElement, TValue>;
// constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
// this.#keySelector = keySelector;
// this.#valueSelector = valueSelector;
// }
// get keySelector() {
// return this.#keySelector;
// }
// get valueSelector() {
// return this.#valueSelector;
// }
// initialize() {
// return new ToObjectCollectorInstance<TElement, TKey, TValue>(this);
// }
// }
// class ToObjectCollectorInstance<TElement, TKey extends PropertyKey, TValue> implements CollectorInstance<TElement, Record<TKey, TValue>> {
// readonly #factory: ToObjectCollectorFactory<TElement, TKey, TValue>;
// readonly #accumulator = <Record<TKey, TValue>>{};
// constructor(factory: ToObjectCollectorFactory<TElement, TKey, TValue>) {
// this.#factory = factory;
// }
// accumulate(element: TElement) {
// const key = this.#factory.keySelector(element);
// const value = this.#factory.valueSelector(element);
// this.#accumulator[key] = value;
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class ToMapCollectorFactory<TElement, TKey extends PropertyKey, TValue> implements CollectorFactory<TElement, Map<TKey, TValue>> {
// readonly #keySelector: Converter<TElement, TKey>;
// readonly #valueSelector: Converter<TElement, TValue>;
// constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
// this.#keySelector = keySelector;
// this.#valueSelector = valueSelector;
// }
// get keySelector() {
// return this.#keySelector;
// }
// get valueSelector() {
// return this.#valueSelector;
// }
// initialize() {
// return new ToMapCollectorInstance<TElement, TKey, TValue>(this);
// }
// }
// class ToMapCollectorInstance<TElement, TKey extends PropertyKey, TValue> implements CollectorInstance<TElement, Map<TKey, TValue>> {
// readonly #factory: ToMapCollectorFactory<TElement, TKey, TValue>;
// readonly #accumulator = new Map<TKey, TValue>();
// constructor(factory: ToMapCollectorFactory<TElement, TKey, TValue>) {
// this.#factory = factory;
// }
// accumulate(element: TElement) {
// const key = this.#factory.keySelector(element);
// const value = this.#factory.valueSelector(element);
// this.#accumulator.set(key, value);
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class ToSetCollectorFactory<TElement> implements CollectorFactory<TElement, Set<TElement>> {
// initialize() {
// return new ToSetCollectorInstance<TElement>();
// }
// }
// class ToSetCollectorInstance<TElement> implements CollectorInstance<TElement, Set<TElement>> {
// readonly #accumulator = new Set<TElement>();
// accumulate(element: TElement) {
// this.#accumulator.add(element);
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class JoinCollectorFactory implements CollectorFactory<any, string> {
// readonly #delimiter: string;
// readonly #prefix: string;
// readonly #suffix: string;
// constructor(delimiter?: string, prefix?: string, suffix?: string) {
// this.#delimiter = delimiter ?? "";
// this.#prefix = prefix ?? "";
// this.#suffix = suffix ?? "";
// }
// accumulate(element: string) {
// this.#accumulator.push(element);
// }
// finalize() {
// return this.#prefix + this.#accumulator.join(this.#delimiter) + this.#suffix;
// }
// }
// class JoinCollectorInstance implements CollectorInstance<any, string> {
// readonly #delimiter: string;
// readonly #prefix: string;
// readonly #suffix: string;
// readonly #accumulator: any[] = [];
// constructor(delimiter: string, prefix: string, suffix: string) {
// this.#delimiter = delimiter ?? "";
// this.#prefix = prefix ?? "";
// this.#suffix = suffix ?? "";
// }
// accumulate(element: string) {
// this.#accumulator.push(element);
// }
// finalize() {
// return this.#prefix + this.#accumulator.join(this.#delimiter) + this.#suffix;
// }
// }
// export class SumCollectorInstance implements CollectorInstance<number, number> {
// #accumulator = 0;
// accumulate(element: number) {
// this.#accumulator += element;
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class BigIntSumCollectorInstance implements CollectorInstance<bigint, bigint> {
// #accumulator = 0n;
// accumulate(element: bigint) {
// this.#accumulator += element;
// }
// finalize() {
// return this.#accumulator;
// }
// }
// export class AverageCollectorInstance implements CollectorInstance<number, number> {
// #count = 0;
// #sum = 0;
// accumulate(element: number) {
// this.#count++;
// this.#sum += element;
// }
// finalize() {
// return this.#count === 0 ? 0 : this.#sum / this.#count;
// }
// }
// export class BigIntAverageCollectorInstance implements CollectorInstance<bigint, bigint> {
// #count = 0n;
// #sum = 0n;
// accumulate(element: bigint) {
// this.#count++;
// this.#sum += element;
// }
// finalize() {
// return this.#count === 0n ? 0n : this.#sum / this.#count;
// }
// }

57
src/collector/v2/index.ts Normal file
View File

@@ -0,0 +1,57 @@
// import { Converter } from "../../types.js";
// import { ToArrayCollectorInstance, ToObjectCollectorInstance, ToMapCollectorInstance, ToSetCollectorInstance, JoinCollectorInstance, SumCollectorInstance, BigIntSumCollectorInstance, AverageCollectorInstance, BigIntAverageCollectorInstance, ToArrayCollectorFactory } from "./impl.js";
// import { CollectorFactory } from "./types.js";
// const toArrayCollectorFactory = new ToArrayCollectorFactory<any>();
// export function toArray<TElement>(): CollectorFactory<TElement, TElement[]> {
// return toArrayCollectorFactory;
// }
// export function toObject<TElement, TKey extends PropertyKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): CollectorFactory<TElement, Record<TKey, TValue>> {
// return () => toObjectCollectorFactory<TElement, TKey, TValue>(keySelector, valueSelector);
// }
// export function toMap<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): CollectorFactory<TElement, Map<TKey, TValue>> {
// return () => new ToMapCollectorInstance<TElement, TKey, TValue>(keySelector, valueSelector);
// }
// export function toSet<TElement>(): CollectorFactory<TElement, Set<TElement>> {
// return () => new ToSetCollectorInstance<TElement>();
// }
// export function join(delimiter?: string, prefix?: string, suffix?: string): CollectorFactory<any, string> {
// return () => new JoinCollectorInstance(delimiter, prefix, suffix);
// }
// function sumCollectorFactory() {
// return new SumCollectorInstance();
// }
// export function sum(): CollectorFactory<number, number> {
// return sumCollectorFactory;
// }
// function bigintSumCollectorFactory() {
// return new BigIntSumCollectorInstance();
// }
// export function bigintSum(): CollectorFactory<bigint | number, bigint> {
// return bigintSumCollectorFactory;
// }
// function averageCollectorFactory() {
// return new AverageCollectorInstance();
// }
// export function average(): CollectorFactory<number, number> {
// return averageCollectorFactory;
// }
// function bigintAverageCollectorFactory() {
// return new BigIntAverageCollectorInstance();
// }
// export function bigintAverage(): CollectorFactory<bigint, bigint> {
// return bigintAverageCollectorFactory;
// }

View File

@@ -0,0 +1,8 @@
// export interface CollectorFactory<TElement, TResult> {
// initialize(): CollectorInstance<TElement, TResult>;
// }
// export interface CollectorInstance<TElement, TResult> {
// accumulate(element: TElement): void;
// finalize(): TResult;
// }