Compare commits
7 Commits
05390027f8
...
85033018cf
| Author | SHA1 | Date | |
|---|---|---|---|
|
85033018cf
|
|||
|
46a3b1741e
|
|||
|
c38092c60e
|
|||
|
7553b70882
|
|||
|
1f8e8039b6
|
|||
|
eda8c8cf5d
|
|||
|
35d284f030
|
@@ -456,6 +456,14 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return new OrderByAsyncSequence<TElement, TBy>(this, true, selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<Awaited<TElement>[]> {
|
||||
return new PartitionAsyncSequence<TElement>(this, equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<Awaited<TElement>[]> {
|
||||
return new PartitionByAsyncSequence<TElement, TBy>(this, selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement> {
|
||||
return new DistinctAsyncSequence<TElement>(this, equater);
|
||||
}
|
||||
@@ -849,6 +857,14 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
|
||||
return this.#sequence.orderByDescending(selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<Awaited<TElement>[]> {
|
||||
return this.#sequence.partition(equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<Awaited<TElement>[]> {
|
||||
return this.#sequence.partitionBy(selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.distinct(equater);
|
||||
}
|
||||
@@ -1284,7 +1300,7 @@ export class ConcatAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
|
||||
@@ -1306,7 +1322,7 @@ export class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
readonly #equater: MaybeAsyncEquater<U> | undefined;
|
||||
@@ -1328,11 +1344,11 @@ export class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class FilterAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class FilterAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #predicate: MaybeAsyncPredicate<T>;
|
||||
|
||||
@@ -1352,7 +1368,7 @@ export class FilterAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class FlatMapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
class FlatMapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #converter: MaybeAsyncConverter<T, MaybeAsyncIterable<U>>;
|
||||
|
||||
@@ -1370,7 +1386,7 @@ export class FlatMapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
}
|
||||
}
|
||||
|
||||
export class IndexedAsyncSequence<T> extends BaseAsyncSequence<[number, Awaited<T>]> {
|
||||
class IndexedAsyncSequence<T> extends BaseAsyncSequence<[number, Awaited<T>]> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>) {
|
||||
@@ -1388,7 +1404,7 @@ export class IndexedAsyncSequence<T> extends BaseAsyncSequence<[number, Awaited<
|
||||
}
|
||||
}
|
||||
|
||||
export class MapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
class MapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #converter: MaybeAsyncConverter<T, U>;
|
||||
|
||||
@@ -1410,7 +1426,7 @@ export class MapperAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class SkipWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #predicate: MaybeAsyncPredicate<T>;
|
||||
|
||||
@@ -1443,7 +1459,7 @@ export class SkipWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class SkipLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1484,7 +1500,7 @@ export class SkipLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class SkipAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1516,7 +1532,7 @@ export class SkipAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class TakeWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #predicate: MaybeAsyncPredicate<T>;
|
||||
|
||||
@@ -1538,7 +1554,7 @@ export class TakeWhileAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class TakeLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1565,7 +1581,7 @@ export class TakeLastAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class TakeAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1598,13 +1614,13 @@ export class TakeAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class OrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
class OrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparer<T>) {
|
||||
super(sequence, sorter ?? defaultArrayComparer, descending);
|
||||
}
|
||||
}
|
||||
|
||||
export class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
super(sequence, OrderByAsyncSequence.#createSorter(selector, sorter), descending);
|
||||
}
|
||||
@@ -1615,13 +1631,13 @@ export class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparer<T>) {
|
||||
super(sequence, combineAsyncComparers(sequence.comparer ?? defaultArrayComparer, sorter ?? defaultArrayComparer), descending);
|
||||
}
|
||||
}
|
||||
|
||||
export class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
super(sequence, ThenOrderByAsyncSequence.#createCombinedSorter(sequence.comparer, selector, sorter), descending);
|
||||
}
|
||||
@@ -1633,7 +1649,7 @@ export class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T>
|
||||
}
|
||||
}
|
||||
|
||||
export class AppendAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class AppendAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #obj: T;
|
||||
|
||||
@@ -1655,7 +1671,7 @@ export class AppendAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class PrependAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class PrependAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #obj: T;
|
||||
|
||||
@@ -1677,7 +1693,7 @@ export class PrependAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class PeekAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class PeekAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #action: MaybeAsyncAction<T>;
|
||||
|
||||
@@ -1700,7 +1716,7 @@ export class PeekAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ZippedAsyncSequence<T, U> extends BaseAsyncSequence<[Awaited<T>, Awaited<U>]> {
|
||||
class ZippedAsyncSequence<T, U> extends BaseAsyncSequence<[Awaited<T>, Awaited<U>]> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<U>;
|
||||
|
||||
@@ -1735,7 +1751,7 @@ export class ZippedAsyncSequence<T, U> extends BaseAsyncSequence<[Awaited<T>, Aw
|
||||
}
|
||||
}
|
||||
|
||||
export class UnionAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class UnionAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
@@ -1763,11 +1779,11 @@ export class UnionAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
@@ -1797,11 +1813,11 @@ export class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
@@ -1827,11 +1843,11 @@ export class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
@@ -1859,11 +1875,11 @@ export class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
@@ -1889,11 +1905,11 @@ export class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class IntersectByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class IntersectByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
@@ -1921,11 +1937,11 @@ export class IntersectByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
await set.clear();
|
||||
set.clear();
|
||||
}
|
||||
}
|
||||
|
||||
export class ReversedAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class ReversedAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>) {
|
||||
@@ -1947,7 +1963,7 @@ export class ReversedAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupByAsyncSequence<TElement, TKey, TResult> extends BaseAsyncSequence<GroupedAsyncSequence<TKey, TResult>> {
|
||||
class GroupByAsyncSequence<TElement, TKey, TResult> extends BaseAsyncSequence<GroupedAsyncSequence<TKey, TResult>> {
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #keySelector: MaybeAsyncConverter<TElement, TKey>;
|
||||
readonly #elementSelector: MaybeAsyncConverter<TElement, TResult>;
|
||||
@@ -1976,13 +1992,13 @@ export class GroupByAsyncSequence<TElement, TKey, TResult> extends BaseAsyncSequ
|
||||
grouping.push(await this.#elementSelector(obj));
|
||||
}
|
||||
|
||||
for await (const entry of groupings) {
|
||||
for (const entry of groupings) {
|
||||
yield new GroupedAsyncSequenceImpl(entry[0], array(entry[1]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class ChunkedAsyncSequence<T> extends BaseAsyncSequence<T[]> {
|
||||
class ChunkedAsyncSequence<T> extends BaseAsyncSequence<T[]> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #size: number;
|
||||
|
||||
@@ -2016,7 +2032,7 @@ export class ChunkedAsyncSequence<T> extends BaseAsyncSequence<T[]> {
|
||||
}
|
||||
}
|
||||
|
||||
export class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence<TResult> {
|
||||
class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence<TResult> {
|
||||
readonly #first: AsyncSequence<TOuter>;
|
||||
readonly #second: AsyncSequence<TInner>;
|
||||
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
|
||||
@@ -2050,7 +2066,7 @@ export class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncS
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence<TResult> {
|
||||
class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence<TResult> {
|
||||
readonly #first: AsyncSequence<TOuter>;
|
||||
readonly #second: AsyncSequence<TInner>;
|
||||
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
|
||||
@@ -2092,7 +2108,7 @@ export class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseA
|
||||
}
|
||||
}
|
||||
|
||||
export class RemoveAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class RemoveAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #obj: T;
|
||||
readonly #all: boolean;
|
||||
@@ -2127,7 +2143,7 @@ export class RemoveAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class CacheAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class CacheAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
#cache: T[] | undefined;
|
||||
|
||||
@@ -2141,3 +2157,62 @@ export class CacheAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
yield* this.#cache ??= await this.#sequence.toArray();
|
||||
}
|
||||
}
|
||||
|
||||
class PartitionAsyncSequence<T> extends BaseAsyncSequence<Awaited<T>[]> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, equater: MaybeAsyncEquater<T> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
this.#equater = equater ?? strictEquals;
|
||||
}
|
||||
|
||||
override async *iterator() {
|
||||
const partitions = createAsyncEqualityMap<T, Awaited<T>[]>(this.#equater);
|
||||
|
||||
for await (const obj of this.#sequence) {
|
||||
const partition = await partitions.get(obj);
|
||||
|
||||
if (partition) {
|
||||
partition.push(obj);
|
||||
} else {
|
||||
await partitions.set(obj, [obj]);
|
||||
}
|
||||
}
|
||||
|
||||
yield* partitions.values();
|
||||
}
|
||||
}
|
||||
|
||||
class PartitionByAsyncSequence<TElement, TBy> extends BaseAsyncSequence<Awaited<TElement>[]> {
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #selector: MaybeAsyncConverter<TElement, TBy>;
|
||||
readonly #equater: MaybeAsyncEquater<TBy>;
|
||||
|
||||
constructor(sequence: AsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater: MaybeAsyncEquater<TBy> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
this.#selector = selector;
|
||||
this.#equater = equater ?? strictEquals;
|
||||
}
|
||||
|
||||
override async *iterator() {
|
||||
const partitions = createAsyncEqualityMap<TBy, Awaited<TElement>[]>(this.#equater);
|
||||
|
||||
for await (const obj of this.#sequence) {
|
||||
const key = await this.#selector(obj);
|
||||
const partition = await partitions.get(key);
|
||||
|
||||
if (partition) {
|
||||
partition.push(obj);
|
||||
} else {
|
||||
await partitions.set(key, [obj]);
|
||||
}
|
||||
}
|
||||
|
||||
yield* partitions.values();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,9 @@ export interface AsyncSequence<TElement> extends AsyncIterable<Awaited<TElement>
|
||||
orderDescending(comparer?: MaybeAsyncComparer<TElement>): AsyncSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<Awaited<TElement>[]>;
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<Awaited<TElement>[]>;
|
||||
|
||||
distinct(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
|
||||
@@ -1,17 +1,24 @@
|
||||
import { Equater, MaybeAsyncEquater } from "./types.js";
|
||||
import { asAsyncGenerator } from "./utils.js";
|
||||
|
||||
export interface EqualityMap<K, V> extends Iterable<[K, V]> {
|
||||
readonly size: number;
|
||||
get(key: K): V | undefined;
|
||||
set(key: K, value: V): V | undefined;
|
||||
contains(key: K): boolean;
|
||||
remove(key: K): V | undefined;
|
||||
clear(): void;
|
||||
keys(): IterableIterator<K>;
|
||||
values(): IterableIterator<V>;
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
}
|
||||
|
||||
class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
readonly #map = new Map<K, V>();
|
||||
|
||||
get size() {
|
||||
return this.#map.size;
|
||||
}
|
||||
|
||||
get(key: K) {
|
||||
return this.#map.get(key);
|
||||
}
|
||||
@@ -36,6 +43,18 @@ class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
this.#map.clear();
|
||||
}
|
||||
|
||||
keys() {
|
||||
return this.#map.keys();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.#map.values();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.#map.entries();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#map[Symbol.iterator]();
|
||||
}
|
||||
@@ -49,6 +68,10 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
this.#keyComparer = keyComparer;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.#list.length;
|
||||
}
|
||||
|
||||
get(key: K) {
|
||||
for (const entry of this.#list) {
|
||||
if (this.#keyComparer(key, entry[0])) {
|
||||
@@ -98,8 +121,26 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
this.#list.length = 0;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#list[Symbol.iterator]();
|
||||
*keys() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry[0];
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry[1];
|
||||
}
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this[Symbol.iterator]();
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (const entry of this.#list) {
|
||||
yield [entry[0], entry[1]] as [K, V]; // no entry mutation allowed!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,17 +148,25 @@ export function createEqualityMap<K, V>(keyComparer?: Equater<K>): EqualityMap<K
|
||||
return keyComparer ? new CustomEqualityMap<K, V>(keyComparer) : new NativeEqualityMap<K, V>();
|
||||
}
|
||||
|
||||
export interface AsyncEqualityMap<K, V> extends AsyncIterable<[K, V]> {
|
||||
export interface AsyncEqualityMap<K, V> extends Iterable<[K, V]> {
|
||||
readonly size: number;
|
||||
get(key: K): Promise<V | undefined>;
|
||||
set(key: K, value: V): Promise<V | undefined>;
|
||||
contains(key: K): Promise<boolean>;
|
||||
remove(key: K): Promise<V | undefined>;
|
||||
clear(): Promise<void>;
|
||||
clear(): void;
|
||||
keys(): IterableIterator<K>;
|
||||
values(): IterableIterator<V>;
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
}
|
||||
|
||||
class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
readonly #map = new Map<K, V>();
|
||||
|
||||
get size() {
|
||||
return this.#map.size;
|
||||
}
|
||||
|
||||
async get(key: K) {
|
||||
return this.#map.get(key);
|
||||
}
|
||||
@@ -138,12 +187,24 @@ class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
return existing;
|
||||
}
|
||||
|
||||
async clear() {
|
||||
clear() {
|
||||
this.#map.clear();
|
||||
}
|
||||
|
||||
[Symbol.asyncIterator]() {
|
||||
return asAsyncGenerator(this.#map[Symbol.iterator]());
|
||||
keys() {
|
||||
return this.#map.keys();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.#map.values();
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this.#map.entries();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#map[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,6 +216,10 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
this.#keyComparer = keyComparer;
|
||||
}
|
||||
|
||||
get size() {
|
||||
return this.#list.length;
|
||||
}
|
||||
|
||||
async get(key: K) {
|
||||
for (const entry of this.#list) {
|
||||
if (await this.#keyComparer(key, entry[0])) {
|
||||
@@ -200,12 +265,30 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async clear() {
|
||||
clear() {
|
||||
this.#list.length = 0;
|
||||
}
|
||||
|
||||
[Symbol.asyncIterator]() {
|
||||
return asAsyncGenerator(this.#list[Symbol.iterator]());
|
||||
*keys() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry[0];
|
||||
}
|
||||
}
|
||||
|
||||
*values() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry[1];
|
||||
}
|
||||
}
|
||||
|
||||
entries() {
|
||||
return this[Symbol.iterator]();
|
||||
}
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (const entry of this.#list) {
|
||||
yield [entry[0], entry[1]] as [K, V]; // no entry mutation allowed!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import { Equater, MaybeAsyncEquater } from "./types.js";
|
||||
import { asAsyncGenerator } from "./utils.js";
|
||||
|
||||
export interface EqualitySet<T> extends Iterable<T> {
|
||||
readonly size: number;
|
||||
@@ -7,6 +6,7 @@ export interface EqualitySet<T> extends Iterable<T> {
|
||||
contains(obj: T): boolean;
|
||||
remove(obj: T): boolean;
|
||||
clear(): void;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
|
||||
class NativeEqualitySet<T> implements EqualitySet<T> {
|
||||
@@ -34,6 +34,10 @@ class NativeEqualitySet<T> implements EqualitySet<T> {
|
||||
this.#set.clear();
|
||||
}
|
||||
|
||||
values() {
|
||||
return this.#set.values();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#set[Symbol.iterator]();
|
||||
}
|
||||
@@ -88,6 +92,10 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
|
||||
this.#list.length = 0;
|
||||
}
|
||||
|
||||
values() {
|
||||
return this[Symbol.iterator]();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#list[Symbol.iterator]();
|
||||
}
|
||||
@@ -97,12 +105,13 @@ export function createEqualitySet<T>(equater?: Equater<T>): EqualitySet<T> {
|
||||
return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet<T>();
|
||||
}
|
||||
|
||||
export interface AsyncEqualitySet<T> extends AsyncIterable<T> {
|
||||
export interface AsyncEqualitySet<T> extends Iterable<T> {
|
||||
readonly size: number;
|
||||
add(obj: T): Promise<boolean>;
|
||||
contains(obj: T): Promise<boolean>;
|
||||
remove(obj: T): Promise<boolean>;
|
||||
clear(): Promise<void>;
|
||||
clear(): void;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
|
||||
class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
@@ -126,12 +135,16 @@ class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
return this.#set.delete(obj);
|
||||
}
|
||||
|
||||
async clear() {
|
||||
clear() {
|
||||
this.#set.clear();
|
||||
}
|
||||
|
||||
[Symbol.asyncIterator]() {
|
||||
return asAsyncGenerator(this.#set[Symbol.iterator]());
|
||||
values() {
|
||||
return this.#set.values();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#set[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,12 +193,16 @@ class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
async clear() {
|
||||
clear() {
|
||||
this.#list.length = 0;
|
||||
}
|
||||
|
||||
[Symbol.asyncIterator]() {
|
||||
return asAsyncGenerator(this.#list[Symbol.iterator]());
|
||||
values() {
|
||||
return this[Symbol.iterator]();
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#list[Symbol.iterator]();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
141
src/sync/impl.ts
141
src/sync/impl.ts
@@ -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);
|
||||
}
|
||||
@@ -1456,7 +1472,7 @@ export class ConcatSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class DistinctSequence<T> extends BaseSequence<T> {
|
||||
class DistinctSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
|
||||
@@ -1482,7 +1498,7 @@ export class DistinctSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class DistinctBySequence<T, U> extends BaseSequence<T> {
|
||||
class DistinctBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
readonly #equater: Equater<U> | undefined;
|
||||
@@ -1510,7 +1526,7 @@ export class DistinctBySequence<T, U> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class WhereSequence<TElement, TFiltered extends TElement> extends BaseSequence<TFiltered> {
|
||||
class WhereSequence<TElement, TFiltered extends TElement> extends BaseSequence<TFiltered> {
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #predicate: FilterPredicate<TElement, TFiltered>;
|
||||
|
||||
@@ -1534,7 +1550,7 @@ export class WhereSequence<TElement, TFiltered extends TElement> extends BaseSeq
|
||||
}
|
||||
}
|
||||
|
||||
export class SelectManySequence<T, U> extends BaseSequence<U> {
|
||||
class SelectManySequence<T, U> extends BaseSequence<U> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #converter: Converter<T, Iterable<U>>;
|
||||
|
||||
@@ -1552,7 +1568,7 @@ export class SelectManySequence<T, U> extends BaseSequence<U> {
|
||||
}
|
||||
}
|
||||
|
||||
export class IndexedSequence<T> extends BaseSequence<[number, T]> {
|
||||
class IndexedSequence<T> extends BaseSequence<[number, T]> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
|
||||
constructor(sequence: Sequence<T>) {
|
||||
@@ -1578,7 +1594,7 @@ export class IndexedSequence<T> extends BaseSequence<[number, T]> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SelectSequence<T, U> extends BaseSequence<U> {
|
||||
class SelectSequence<T, U> extends BaseSequence<U> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #converter: Converter<T, U>;
|
||||
|
||||
@@ -1604,7 +1620,7 @@ export class SelectSequence<T, U> extends BaseSequence<U> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipWhileSequence<T> extends BaseSequence<T> {
|
||||
class SkipWhileSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #predicate: Predicate<T>;
|
||||
|
||||
@@ -1633,7 +1649,7 @@ export class SkipWhileSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipLastSequence<T> extends BaseSequence<T> {
|
||||
class SkipLastSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1678,7 +1694,7 @@ export class SkipLastSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SkipSequence<T> extends BaseSequence<T> {
|
||||
class SkipSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1714,7 +1730,7 @@ export class SkipSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeWhileSequence<T> extends BaseSequence<T> {
|
||||
class TakeWhileSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #predicate: Predicate<T>;
|
||||
|
||||
@@ -1740,7 +1756,7 @@ export class TakeWhileSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeLastSequence<T> extends BaseSequence<T> {
|
||||
class TakeLastSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1771,7 +1787,7 @@ export class TakeLastSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class TakeSequence<T> extends BaseSequence<T> {
|
||||
class TakeSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #n: number;
|
||||
|
||||
@@ -1808,13 +1824,13 @@ export class TakeSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class OrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
class OrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: Sequence<T>, descending: boolean, sorter?: Comparer<T>) {
|
||||
super(sequence, sorter, descending);
|
||||
}
|
||||
}
|
||||
|
||||
export class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: Sequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
super(sequence, OrderBySequence.#createSorter(selector, sorter), descending);
|
||||
}
|
||||
@@ -1825,13 +1841,13 @@ export class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ThenOrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
class ThenOrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: Comparer<T>) {
|
||||
super(sequence, combineComparers(sequence.comparer ?? defaultArrayComparer, sorter ?? defaultArrayComparer), descending);
|
||||
}
|
||||
}
|
||||
|
||||
export class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
super(sequence, ThenOrderBySequence.#createCombinedSorter(sequence.comparer, selector, sorter), descending);
|
||||
}
|
||||
@@ -1843,7 +1859,7 @@ export class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class AppendSequence<T> extends BaseSequence<T> {
|
||||
class AppendSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #obj: T;
|
||||
|
||||
@@ -1869,7 +1885,7 @@ export class AppendSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class PrependSequence<T> extends BaseSequence<T> {
|
||||
class PrependSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #obj: T;
|
||||
|
||||
@@ -1895,7 +1911,7 @@ export class PrependSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class PeekSequence<T> extends DelegatedSequence<T> {
|
||||
class PeekSequence<T> extends DelegatedSequence<T> {
|
||||
readonly #action: Action<T>;
|
||||
|
||||
constructor(sequence: Sequence<T>, action: Action<T>) {
|
||||
@@ -1912,7 +1928,7 @@ export class PeekSequence<T> extends DelegatedSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ZippedSequence<T, U> extends BaseSequence<[T, U]> {
|
||||
class ZippedSequence<T, U> extends BaseSequence<[T, U]> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<U>;
|
||||
|
||||
@@ -1951,7 +1967,7 @@ export class ZippedSequence<T, U> extends BaseSequence<[T, U]> {
|
||||
}
|
||||
}
|
||||
|
||||
export class UnionSequence<T> extends BaseSequence<T> {
|
||||
class UnionSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
@@ -1984,7 +2000,7 @@ export class UnionSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class UnionBySequence<T, U> extends BaseSequence<T> {
|
||||
class UnionBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
@@ -2019,7 +2035,7 @@ export class UnionBySequence<T, U> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExceptSequence<T> extends BaseSequence<T> {
|
||||
class ExceptSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
@@ -2051,7 +2067,7 @@ export class ExceptSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExceptBySequence<T, U> extends BaseSequence<T> {
|
||||
class ExceptBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
@@ -2085,7 +2101,7 @@ export class ExceptBySequence<T, U> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class IntersectSequence<T> extends BaseSequence<T> {
|
||||
class IntersectSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
@@ -2117,7 +2133,7 @@ export class IntersectSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class IntersectBySequence<T, U> extends BaseSequence<T> {
|
||||
class IntersectBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
@@ -2151,7 +2167,7 @@ export class IntersectBySequence<T, U> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class ReversedSequence<T> extends BaseSequence<T> {
|
||||
class ReversedSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
|
||||
constructor(sequence: Sequence<T>) {
|
||||
@@ -2181,7 +2197,7 @@ export class ReversedSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupBySequence<TElement, TKey, TResult> extends BaseSequence<GroupedSequence<TKey, TResult>> {
|
||||
class GroupBySequence<TElement, TKey, TResult> extends BaseSequence<GroupedSequence<TKey, TResult>> {
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #keySelector: Converter<TElement, TKey>;
|
||||
readonly #elementSelector: Converter<TElement, TResult>;
|
||||
@@ -2220,7 +2236,7 @@ export class GroupBySequence<TElement, TKey, TResult> extends BaseSequence<Group
|
||||
}
|
||||
}
|
||||
|
||||
export class ChunkedSequence<T> extends BaseSequence<T[]> {
|
||||
class ChunkedSequence<T> extends BaseSequence<T[]> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #size: number;
|
||||
|
||||
@@ -2258,7 +2274,7 @@ export class ChunkedSequence<T> extends BaseSequence<T[]> {
|
||||
}
|
||||
}
|
||||
|
||||
export class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult> {
|
||||
class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult> {
|
||||
readonly #first: Sequence<TOuter>;
|
||||
readonly #second: Sequence<TInner>;
|
||||
readonly #firstKeySelector: Converter<TOuter, TKey>;
|
||||
@@ -2300,7 +2316,7 @@ export class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TR
|
||||
}
|
||||
}
|
||||
|
||||
export class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult> {
|
||||
class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult> {
|
||||
readonly #first: Sequence<TOuter>;
|
||||
readonly #second: Sequence<TInner>;
|
||||
readonly #firstKeySelector: Converter<TOuter, TKey>;
|
||||
@@ -2349,7 +2365,7 @@ export class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequen
|
||||
}
|
||||
}
|
||||
|
||||
export class RemoveSequence<T> extends BaseSequence<T> {
|
||||
class RemoveSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #obj: T;
|
||||
readonly #all: boolean;
|
||||
@@ -2388,7 +2404,7 @@ export class RemoveSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export class CacheSequence<T> extends DelegatedSequence<T> {
|
||||
class CacheSequence<T> extends DelegatedSequence<T> {
|
||||
#cached = false;
|
||||
|
||||
constructor(sequence: Sequence<T>) {
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,9 @@ export interface Sequence<TElement> extends Iterable<TElement> {
|
||||
orderDescending(comparer?: Comparer<TElement>): OrderedSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement>;
|
||||
|
||||
partition(equater?: Equater<TElement>): Sequence<TElement[]>;
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement[]>;
|
||||
|
||||
distinct(equater?: Equater<TElement>): Sequence<TElement>;
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user