1
0

add sequence partition operation

This commit is contained in:
2024-05-13 23:12:46 +02:00
parent c38092c60e
commit 46a3b1741e
4 changed files with 156 additions and 0 deletions

View File

@@ -454,6 +454,14 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
return new OrderBySequence<TElement, TBy>(this, true, selector, comparer);
}
partition(equater?: Equater<TElement>): Sequence<TElement[]> {
return new PartitionSequence<TElement>(this, equater);
}
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement[]> {
return new PartitionBySequence<TElement, TBy>(this, selector, equater);
}
distinct(equater?: Equater<TElement>): Sequence<TElement> {
return new DistinctSequence<TElement>(this, equater);
}
@@ -833,6 +841,14 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
return this.#sequence.orderByDescending(selector, comparer);
}
partition(equater?: Equater<TElement> | undefined): Sequence<TElement[]> {
return this.#sequence.partition(equater);
}
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy> | undefined): Sequence<TElement[]> {
return this.#sequence.partitionBy(selector, equater);
}
distinct(equater?: Equater<TElement>) {
return this.#sequence.distinct(equater);
}
@@ -2404,3 +2420,62 @@ export class CacheSequence<T> extends DelegatedSequence<T> {
return super.iterator();
}
}
class PartitionSequence<T> extends BaseSequence<T[]> {
readonly #sequence: Sequence<T>;
readonly #equater: Equater<T>;
constructor(sequence: Sequence<T>, equater: Equater<T> | undefined) {
super();
this.#sequence = sequence;
this.#equater = equater ?? strictEquals;
}
override *iterator() {
const partitions = createEqualityMap<T, T[]>(this.#equater);
for (const obj of this.#sequence) {
const partition = partitions.get(obj);
if (partition) {
partition.push(obj);
} else {
partitions.set(obj, [obj]);
}
}
yield* partitions.values();
}
}
class PartitionBySequence<TElement, TBy> extends BaseSequence<TElement[]> {
readonly #sequence: Sequence<TElement>;
readonly #selector: Converter<TElement, TBy>;
readonly #equater: Equater<TBy>;
constructor(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater: Equater<TBy> | undefined) {
super();
this.#sequence = sequence;
this.#selector = selector;
this.#equater = equater ?? strictEquals;
}
override *iterator() {
const partitions = createEqualityMap<TBy, TElement[]>(this.#equater);
for (const obj of this.#sequence) {
const key = this.#selector(obj);
const partition = partitions.get(key);
if (partition) {
partition.push(obj);
} else {
partitions.set(key, [obj]);
}
}
yield* partitions.values();
}
}