From 595d9fd5fcbd4f7ac01bbf819a824612f0cbd380 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20BECHER?= Date: Fri, 17 May 2024 22:12:16 +0200 Subject: [PATCH] sequence type fixes and refactor --- src/async/impl.ts | 272 +++++++++++++++++++++++---------------------- src/async/index.ts | 26 +++-- src/async/types.ts | 44 ++++---- src/sync/impl.ts | 153 +++++++++++++------------ src/sync/index.ts | 4 +- src/sync/types.ts | 30 ++--- src/types.ts | 7 +- 7 files changed, 287 insertions(+), 249 deletions(-) diff --git a/src/async/impl.ts b/src/async/impl.ts index d8b0d9f..f9f0f44 100644 --- a/src/async/impl.ts +++ b/src/async/impl.ts @@ -6,7 +6,7 @@ import { getRandomElementAsync } from "../random/index.js"; import { AsyncRandomOptions } from "../random/types.js"; import { selectionSorter } from "../sorting.js"; import { Sequence } from "../sync/types.js"; -import { MaybeAsyncConverter, MaybeAsyncIterable, MaybeAsyncPredicate, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybePromise, Predicate } from "../types.js"; +import { MaybeAsyncConverter, MaybeAsyncPredicate, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybeAsyncSequence } from "../types.js"; import { strictEquals, identity, operatorCompare, asAsyncGenerator, defaultArrayComparer, combineAsyncComparers } from "../utils.js"; import { array, empty, wrap } from "./index.js"; import { AsyncSequence, GroupedAsyncSequence, OrderedAsyncSequence } from "./types.js"; @@ -18,7 +18,7 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return this.iterator(); } - abstract iterator(): AsyncIterator>; + abstract iterator(): AsyncIterator; apply(pipeline: (sequence: AsyncSequence) => TResult): TResult { return pipeline(this); @@ -28,7 +28,7 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new MapperAsyncSequence(this, converter); } - selectMany(converter: MaybeAsyncConverter>): AsyncSequence { + selectMany(converter: MaybeAsyncConverter>): AsyncSequence { return new FlatMapperAsyncSequence(this, converter); } @@ -36,16 +36,22 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new FilterAsyncSequence(this, predicate); } - groupBy(keySelector: MaybeAsyncConverter, elementSelector?: MaybeAsyncConverter, keyComparer?: MaybeAsyncEquater): AsyncSequence> { - return new GroupByAsyncSequence(this, keySelector, elementSelector, keyComparer); + groupBy(keySelector: MaybeAsyncConverter, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; + groupBy(keySelector: MaybeAsyncConverter, elementSelector: MaybeAsyncConverter, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; + groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { + return new GroupByAsyncSequence(this, keySelector, elementSelector, keyComparer); } - join(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: MaybeAsyncBiConverter, keyComparer?: MaybeAsyncEquater): AsyncSequence { - return new JoinAsyncSequence(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer); + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence<[TElement, TOther]>; + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence; + join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return new JoinAsyncSequence(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); } - groupJoin(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: MaybeAsyncBiConverter, TResult>, keyComparer?: MaybeAsyncEquater): AsyncSequence { - return new GroupJoinAsyncSequence(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer); + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, TResult>, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence; + groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return new GroupJoinAsyncSequence(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer); } async contains(obj: TElement, equater?: MaybeAsyncEquater) { @@ -62,12 +68,12 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return false; } - async sequenceEquals(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater) { - if (this === iterable) { + async sequenceEquals(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater) { + if (this === sequence) { return true; } - const that = wrap(iterable); + const that = wrap(sequence); const thisCount = await this.nonEnumeratedCount(); const thatCount = await that.nonEnumeratedCount(); @@ -113,15 +119,15 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new RemoveAsyncSequence(this, obj, all, equater); } - concat(...iterables: MaybeAsyncIterable[]): AsyncSequence { - if (iterables.length === 0) { + concat(...sequences: MaybeAsyncSequence[]): AsyncSequence { + if (sequences.length === 0) { return this; } const arr: AsyncSequence[] = [this]; - for (const iterable of iterables) { - arr.push(wrap(iterable)); + for (const sequence of sequences) { + arr.push(wrap(sequence)); } return new ConcatAsyncSequence(arr); @@ -456,11 +462,11 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new OrderByAsyncSequence(this, true, selector, comparer); } - partition(equater?: MaybeAsyncEquater): AsyncSequence[]> { + partition(equater?: MaybeAsyncEquater): AsyncSequence { return new PartitionAsyncSequence(this, equater); } - partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence[]> { + partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence { return new PartitionByAsyncSequence(this, selector, equater); } @@ -472,28 +478,28 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new DistinctByAsyncSequence(this, selector, equater); } - union(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater): AsyncSequence { - return new UnionAsyncSequence(this, wrap(iterable), equater); + union(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater): AsyncSequence { + return new UnionAsyncSequence(this, wrap(sequence), equater); } - unionBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence { - return new UnionByAsyncSequence(this, wrap(iterable), selector, equater); + unionBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence { + return new UnionByAsyncSequence(this, wrap(sequence), selector, equater); } - except(iterable: MaybeAsyncIterable): AsyncSequence { - return new ExceptAsyncSequence(this, wrap(iterable)); + except(sequence: MaybeAsyncSequence): AsyncSequence { + return new ExceptAsyncSequence(this, wrap(sequence)); } - exceptBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter): AsyncSequence { - return new ExceptByAsyncSequence(this, wrap(iterable), selector); + exceptBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter): AsyncSequence { + return new ExceptByAsyncSequence(this, wrap(sequence), selector); } - intersect(iterable: MaybeAsyncIterable): AsyncSequence { - return new IntersectAsyncSequence(this, wrap(iterable)); + intersect(sequence: MaybeAsyncSequence): AsyncSequence { + return new IntersectAsyncSequence(this, wrap(sequence)); } - intersectBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter): AsyncSequence { - return new IntersectByAsyncSequence(this, wrap(iterable), selector); + intersectBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter): AsyncSequence { + return new IntersectByAsyncSequence(this, wrap(sequence), selector); } async all(predicate: MaybeAsyncPredicate) { @@ -602,11 +608,11 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im } } - zip(iterable: MaybeAsyncIterable): AsyncSequence<[Awaited, Awaited]> { - return new ZippedAsyncSequence(this, wrap(iterable)); + zip(sequence: MaybeAsyncSequence): AsyncSequence<[TElement, TOther]> { + return new ZippedAsyncSequence(this, wrap(sequence)); } - indexex(): AsyncSequence<[number, Awaited]> { + indexex(): AsyncSequence<[number, TElement]> { return new IndexedAsyncSequence(this); } @@ -630,6 +636,10 @@ export abstract class BaseAsyncSequence extends AsyncSequenceMarker im return new CacheAsyncSequence(this); } + async asArray(): Promise { + return await this.toArray(); + } + async toArray() { const array: TElement[] = []; @@ -716,7 +726,7 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.apply(pipeline); } - count(predicate?: ((obj: TElement) => MaybePromise) | undefined): Promise { + count(predicate?: MaybeAsyncPredicate | undefined): Promise { return this.#sequence.count(predicate); } @@ -732,42 +742,42 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.maxCount(); } - select(selector: (obj: TElement) => MaybePromise): AsyncSequence { + select(selector: MaybeAsyncConverter): AsyncSequence { return this.#sequence.select(selector); } - selectMany(selector: (obj: TElement) => MaybePromise>): AsyncSequence { + selectMany(selector: MaybeAsyncConverter>): AsyncSequence { return this.#sequence.selectMany(selector); } - where(predicate: (obj: TElement) => MaybePromise): AsyncSequence { + where(predicate: MaybeAsyncPredicate): AsyncSequence { return this.#sequence.where(predicate); } - groupBy(keySelector: (obj: TElement) => MaybePromise, elementSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence>; - groupBy(keySelector: (obj: TElement) => MaybePromise, elementSelector: (obj: TElement) => MaybePromise, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence>; + groupBy(keySelector: MaybeAsyncConverter, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; + groupBy(keySelector: MaybeAsyncConverter, elementSelector: MaybeAsyncConverter, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { return this.#sequence.groupBy(keySelector, elementSelector, keyComparer); } - join(iterable: MaybeAsyncIterable, firstKeySelector: (obj: TElement) => MaybePromise, secondKeySelector: (obj: TOther) => MaybePromise, resultSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence<[Awaited, Awaited]>; - join(iterable: MaybeAsyncIterable, firstKeySelector: (obj: TElement) => MaybePromise, secondKeySelector: (obj: TOther) => MaybePromise, resultSelector: (first: TElement, second: TOther) => MaybePromise, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence; - join(iterable: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { - return this.#sequence.join(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer); + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence<[TElement, TOther]>; + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence; + join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } - groupJoin(iterable: MaybeAsyncIterable, firstKeySelector: (obj: TElement) => MaybePromise, secondKeySelector: (obj: TOther) => MaybePromise, resultSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence>; - groupJoin(iterable: MaybeAsyncIterable, firstKeySelector: (obj: TElement) => MaybePromise, secondKeySelector: (obj: TOther) => MaybePromise, resultSelector: (first: TElement, second: AsyncSequence) => MaybePromise, keyComparer?: ((first: TKey, second: TKey) => MaybePromise) | undefined): AsyncSequence; - groupJoin(iterable: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { - return this.#sequence.groupJoin(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer); + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence>; + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, TResult>, keyComparer?: MaybeAsyncEquater | undefined): AsyncSequence; + groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } - contains(obj: TElement, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): Promise { + contains(obj: TElement, equater?: MaybeAsyncEquater | undefined): Promise { return this.#sequence.contains(obj, equater); } - sequenceEquals(iterable: MaybeAsyncIterable, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): Promise { - return this.#sequence.sequenceEquals(iterable, equater); + sequenceEquals(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater | undefined): Promise { + return this.#sequence.sequenceEquals(sequence, equater); } append(obj: TElement): AsyncSequence { @@ -778,35 +788,35 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.prepend(obj); } - remove(obj: TElement, all?: boolean | undefined, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { + remove(obj: TElement, all?: boolean | undefined, equater?: MaybeAsyncEquater | undefined): AsyncSequence { return this.#sequence.remove(obj, all, equater); } - concat(...iterables: MaybeAsyncIterable[]): AsyncSequence { - return this.#sequence.concat(...iterables); + concat(...sequences: MaybeAsyncSequence[]): AsyncSequence { + return this.#sequence.concat(...sequences); } - first(predicate?: ((obj: TElement) => MaybePromise) | undefined): Promise { + first(predicate?: MaybeAsyncPredicate | undefined): Promise { return this.#sequence.first(predicate); } - firstOrDefault(predicate?: ((obj: TElement) => MaybePromise) | undefined, def?: TElement | undefined): Promise { + firstOrDefault(predicate?: MaybeAsyncPredicate | undefined, def?: TElement | undefined): Promise { return this.#sequence.firstOrDefault(predicate, def); } - last(predicate?: ((obj: TElement) => MaybePromise) | undefined): Promise { + last(predicate?: MaybeAsyncPredicate | undefined): Promise { return this.#sequence.last(predicate); } - lastOrDefault(predicate?: ((obj: TElement) => MaybePromise) | undefined, def?: TElement | undefined): Promise { + lastOrDefault(predicate?: MaybeAsyncPredicate | undefined, def?: TElement | undefined): Promise { return this.#sequence.lastOrDefault(predicate, def); } - single(predicate?: ((obj: TElement) => MaybePromise) | undefined): Promise { + single(predicate?: MaybeAsyncPredicate | undefined): Promise { return this.#sequence.single(predicate); } - singleOrDefault(predicate?: ((obj: TElement) => MaybePromise) | undefined, def?: TElement | undefined): Promise { + singleOrDefault(predicate?: MaybeAsyncPredicate | undefined, def?: TElement | undefined): Promise { return this.#sequence.singleOrDefault(predicate, def); } @@ -818,9 +828,9 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.elementAtOrDefault(index, def); } - aggregate(accumulator: (acc: TElement, obj: TElement) => MaybePromise): Promise; - aggregate(accumulator: (acc: TAccumulator, obj: TElement) => MaybePromise, seed?: TAccumulator | undefined): Promise; - aggregate(accumulator: (acc: TAccumulator, obj: TElement) => MaybePromise, seed?: TAccumulator | undefined, resultSelector?: ((obj: TAccumulator) => MaybePromise) | undefined): Promise; + aggregate(accumulator: MaybeAsyncAccumulator): Promise; + aggregate(accumulator: MaybeAsyncAccumulator, seed?: TAccumulator | undefined): Promise; + aggregate(accumulator: MaybeAsyncAccumulator, seed?: TAccumulator | undefined, resultSelector?: MaybeAsyncConverter | undefined): Promise; aggregate(accumulator: any, seed?: any, resultSelector?: any) { return this.#sequence.aggregate(accumulator, seed, resultSelector); } @@ -829,7 +839,7 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.min(); } - minBy(selector: (obj: TElement) => MaybePromise): Promise { + minBy(selector: MaybeAsyncConverter): Promise { return this.#sequence.minBy(selector); } @@ -837,77 +847,77 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.max(); } - maxBy(selector: (obj: TElement) => MaybePromise): Promise { + maxBy(selector: MaybeAsyncConverter): Promise { return this.#sequence.maxBy(selector); } - order(comparer?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { + order(comparer?: MaybeAsyncComparer | undefined): AsyncSequence { return this.#sequence.order(comparer); } - orderBy(selector: (obj: TElement) => MaybePromise, comparer?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { + orderBy(selector: MaybeAsyncConverter, comparer?: MaybeAsyncComparer | undefined): AsyncSequence { return this.#sequence.orderBy(selector, comparer); } - orderDescending(comparer?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { + orderDescending(comparer?: MaybeAsyncComparer | undefined): AsyncSequence { return this.#sequence.orderDescending(comparer); } - orderByDescending(selector: (obj: TElement) => MaybePromise, comparer?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { + orderByDescending(selector: MaybeAsyncConverter, comparer?: MaybeAsyncComparer | undefined): AsyncSequence { return this.#sequence.orderByDescending(selector, comparer); } - partition(equater?: MaybeAsyncEquater | undefined): AsyncSequence[]> { + partition(equater?: MaybeAsyncEquater | undefined): AsyncSequence { return this.#sequence.partition(equater); } - partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence[]> { + partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence { return this.#sequence.partitionBy(selector, equater); } - distinct(equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { + distinct(equater?: MaybeAsyncEquater | undefined): AsyncSequence { return this.#sequence.distinct(equater); } - distinctBy(selector: (obj: TElement) => MaybePromise, equater?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { + distinctBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence { return this.#sequence.distinctBy(selector, equater); } - union(iterable: MaybeAsyncIterable, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.union(iterable, equater); + union(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.union(wrap(sequence), equater); } - unionBy(iterable: MaybeAsyncIterable, selector: (obj: TElement) => MaybePromise, equater?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.unionBy(iterable, selector, equater); + unionBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.unionBy(wrap(sequence), selector, equater); } - except(iterable: MaybeAsyncIterable, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.except(iterable, equater); + except(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.except(wrap(sequence), equater); } - exceptBy(iterable: MaybeAsyncIterable, selector: (obj: TElement) => MaybePromise, equater?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.exceptBy(iterable, selector, equater); + exceptBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.exceptBy(wrap(sequence), selector, equater); } - intersect(iterable: MaybeAsyncIterable, equater?: ((first: TElement, second: TElement) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.intersect(iterable, equater); + intersect(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.intersect(wrap(sequence), equater); } - intersectBy(iterable: MaybeAsyncIterable, selector: (obj: TElement) => MaybePromise, equater?: ((first: TBy, second: TBy) => MaybePromise) | undefined): AsyncSequence { - return this.#sequence.intersectBy(iterable, selector, equater); + intersectBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater | undefined): AsyncSequence { + return this.#sequence.intersectBy(wrap(sequence), selector, equater); } - all(predicate: (obj: TElement) => MaybePromise): Promise { + all(predicate: MaybeAsyncPredicate): Promise { return this.#sequence.all(predicate); } - any(predicate: (obj: TElement) => MaybePromise): Promise; + any(predicate: MaybeAsyncPredicate): Promise; any(): Promise; any(predicate?: any) { return this.#sequence.any(predicate); } - none(predicate: Predicate): Promise; + none(predicate: MaybeAsyncPredicate): Promise; none(): Promise; none(predicate?: any) { return this.#sequence.none(predicate); @@ -921,7 +931,7 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.skipLast(n); } - skipWhile(condition: (obj: TElement) => MaybePromise): AsyncSequence { + skipWhile(condition: MaybeAsyncPredicate): AsyncSequence { return this.#sequence.skipWhile(condition); } @@ -933,23 +943,23 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.takeLast(n); } - takeWhile(condition: (obj: TElement) => MaybePromise): AsyncSequence { + takeWhile(condition: MaybeAsyncPredicate): AsyncSequence { return this.#sequence.takeWhile(condition); } - peek(action: (obj: TElement) => MaybePromise): AsyncSequence { + peek(action: MaybeAsyncAction): AsyncSequence { return this.#sequence.peek(action); } - forEach(action: (obj: TElement) => MaybePromise): Promise { + forEach(action: MaybeAsyncAction): Promise { return this.#sequence.forEach(action); } - zip(iterable: MaybeAsyncIterable): AsyncSequence<[Awaited, Awaited]> { - return this.#sequence.zip(iterable); + zip(sequence: MaybeAsyncSequence): AsyncSequence<[TElement, TOther]> { + return this.#sequence.zip(wrap(sequence)); } - indexex(): AsyncSequence<[number, Awaited]> { + indexex(): AsyncSequence<[number, TElement]> { return this.#sequence.indexex(); } @@ -969,11 +979,15 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.cached(); } + asArray(): Promise { + return this.#sequence.asArray(); + } + toArray(): Promise { return this.#sequence.toArray(); } - toMap(keySelector: (obj: TElement) => MaybePromise, valueSelector: (obj: TElement) => MaybePromise): Promise> { + toMap(keySelector: MaybeAsyncConverter, valueSelector: MaybeAsyncConverter): Promise> { return this.#sequence.toMap(keySelector, valueSelector); } @@ -981,7 +995,7 @@ export class DelegatedAsyncSequence extends AsyncSequenceMarker implem return this.#sequence.toSet(); } - toObject(keySelector: (obj: TElement) => MaybePromise, valueSelector: (obj: TElement) => MaybePromise): Promise> { + toObject(keySelector: MaybeAsyncConverter, valueSelector: MaybeAsyncConverter): Promise> { return this.#sequence.toObject(keySelector, valueSelector); } @@ -1059,15 +1073,11 @@ abstract class BaseOrderedAsyncSequence extends BaseAsyncSequence extends BaseAsyncSequence { - static readonly INSTANCE = new EmptyAsyncSequence(); - override async nonEnumeratedCount() { return 0; } - override async *iterator() { - - } + override async *iterator() { } } export class RangeAsyncSequence extends BaseAsyncSequence { @@ -1095,10 +1105,10 @@ export class RangeAsyncSequence extends BaseAsyncSequence { } export class RepeatAsyncSequence extends BaseAsyncSequence { - readonly #value: T; + readonly #value: MaybePromiseLike; readonly #count: number; - constructor(value: T, count: number) { + constructor(value: MaybePromiseLike, count: number) { super(); this.#value = value; @@ -1119,9 +1129,9 @@ export class RepeatAsyncSequence extends BaseAsyncSequence { } export class RepeatForeverAsyncSequence extends BaseAsyncSequence { - readonly #value: T; + readonly #value: MaybePromiseLike; - constructor(value: T) { + constructor(value: MaybePromiseLike) { super(); this.#value = value; @@ -1139,9 +1149,9 @@ export class RepeatForeverAsyncSequence extends BaseAsyncSequence { } export class WrappedObjectAsync extends BaseAsyncSequence { - readonly #obj: T | PromiseLike; + readonly #obj: MaybePromiseLike; - constructor(obj: T | PromiseLike) { + constructor(obj: MaybePromiseLike) { super(); this.#obj = obj; @@ -1157,9 +1167,9 @@ export class WrappedObjectAsync extends BaseAsyncSequence { } export class WrappedArrayAsync extends BaseAsyncSequence { - readonly #array: (T | PromiseLike)[]; + readonly #array: MaybePromiseLike[]; - constructor(array: (T | PromiseLike)[]) { + constructor(array: MaybePromiseLike[]) { super(); this.#array = array; @@ -1175,9 +1185,9 @@ export class WrappedArrayAsync extends BaseAsyncSequence { } export class WrappedArrayLikeAsync extends BaseAsyncSequence { - readonly #arrayLike: ArrayLike>; + readonly #arrayLike: ArrayLike>; - constructor(arrayLike: ArrayLike>) { + constructor(arrayLike: ArrayLike>) { super(); this.#arrayLike = arrayLike; @@ -1195,9 +1205,9 @@ export class WrappedArrayLikeAsync extends BaseAsyncSequence { } export class WrappedAsyncIterable extends BaseAsyncSequence { - readonly #iterable: AsyncIterable; + readonly #iterable: AsyncIterable>; - constructor(iterable: AsyncIterable) { + constructor(iterable: AsyncIterable>) { super(); this.#iterable = iterable; @@ -1209,9 +1219,9 @@ export class WrappedAsyncIterable extends BaseAsyncSequence { } export class GeneratorAsyncSequence extends BaseAsyncSequence { - readonly #generator: () => AsyncGenerator; + readonly #generator: () => MaybeAsyncGenerator>; - constructor(generator: () => AsyncGenerator) { + constructor(generator: () => MaybeAsyncGenerator>) { super(); this.#generator = generator; @@ -1223,9 +1233,9 @@ export class GeneratorAsyncSequence extends BaseAsyncSequence { } export class FunctionAsyncSequence extends BaseAsyncSequence { - readonly #f: () => MaybePromise; + readonly #f: () => MaybePromiseLike; - constructor(f: () => MaybePromise) { + constructor(f: () => MaybePromiseLike) { super(); this.#f = f; @@ -1243,9 +1253,9 @@ export class FunctionAsyncSequence extends BaseAsyncSequence { } export class WrappedSequence extends BaseAsyncSequence { - readonly #sequence: Sequence; + readonly #sequence: Sequence>; - constructor(sequence: Sequence) { + constructor(sequence: Sequence>) { super(); this.#sequence = sequence; @@ -1280,8 +1290,8 @@ export class ConcatAsyncSequence extends BaseAsyncSequence { override async nonEnumeratedCount() { let n = 0; - for (const iterable of this.#sequences) { - const m = await iterable.nonEnumeratedCount(); + for (const sequence of this.#sequences) { + const m = await sequence.nonEnumeratedCount(); if (m < 0) { return -1; @@ -1370,9 +1380,9 @@ class FilterAsyncSequence extends BaseAsyncSequence { class FlatMapperAsyncSequence extends BaseAsyncSequence { readonly #sequence: AsyncSequence; - readonly #converter: MaybeAsyncConverter>; + readonly #converter: MaybeAsyncConverter>; - constructor(sequence: AsyncSequence, converter: MaybeAsyncConverter>) { + constructor(sequence: AsyncSequence, converter: MaybeAsyncConverter>) { super(); this.#sequence = sequence; @@ -1386,7 +1396,7 @@ class FlatMapperAsyncSequence extends BaseAsyncSequence { } } -class IndexedAsyncSequence extends BaseAsyncSequence<[number, Awaited]> { +class IndexedAsyncSequence extends BaseAsyncSequence<[number, T]> { readonly #sequence: AsyncSequence; constructor(sequence: AsyncSequence) { @@ -1399,7 +1409,7 @@ class IndexedAsyncSequence extends BaseAsyncSequence<[number, Awaited]> { let i = 0; for await (const obj of this.#sequence) { - yield [i++, obj] as [number, Awaited]; + yield [i++, obj] as [number, T]; } } } @@ -1716,7 +1726,7 @@ class PeekAsyncSequence extends BaseAsyncSequence { } } -class ZippedAsyncSequence extends BaseAsyncSequence<[Awaited, Awaited]> { +class ZippedAsyncSequence extends BaseAsyncSequence<[T, U]> { readonly #first: AsyncSequence; readonly #second: AsyncSequence; @@ -1746,7 +1756,7 @@ class ZippedAsyncSequence extends BaseAsyncSequence<[Awaited, Awaited, Awaited]; + yield [firstNext.value, secondNext.value] as [T, U]; } } } @@ -2158,7 +2168,7 @@ class CacheAsyncSequence extends BaseAsyncSequence { } } -class PartitionAsyncSequence extends BaseAsyncSequence[]> { +class PartitionAsyncSequence extends BaseAsyncSequence { readonly #sequence: AsyncSequence; readonly #equater: MaybeAsyncEquater; @@ -2170,7 +2180,7 @@ class PartitionAsyncSequence extends BaseAsyncSequence[]> { } override async *iterator() { - const partitions = createAsyncEqualityMap[]>(this.#equater); + const partitions = createAsyncEqualityMap(this.#equater); for await (const obj of this.#sequence) { const partition = await partitions.get(obj); @@ -2186,7 +2196,7 @@ class PartitionAsyncSequence extends BaseAsyncSequence[]> { } } -class PartitionByAsyncSequence extends BaseAsyncSequence[]> { +class PartitionByAsyncSequence extends BaseAsyncSequence { readonly #sequence: AsyncSequence; readonly #selector: MaybeAsyncConverter; readonly #equater: MaybeAsyncEquater; @@ -2200,7 +2210,7 @@ class PartitionByAsyncSequence extends BaseAsyncSequence[]>(this.#equater); + const partitions = createAsyncEqualityMap(this.#equater); for await (const obj of this.#sequence) { const key = await this.#selector(obj); diff --git a/src/async/index.ts b/src/async/index.ts index 0e5135b..3306d26 100644 --- a/src/async/index.ts +++ b/src/async/index.ts @@ -1,15 +1,15 @@ import { wrap as wrapSync } from "../sync/index.js"; import { Sequence } from "../sync/types.js"; -import { MaybeAsyncIterable } from "../types.js"; +import { MaybeAsyncGenerator, MaybeAsyncIterable, MaybeAsyncSequence, MaybePromiseLike } from "../types.js"; import { isAsyncIterable } from "../utils.js"; import { WrappedSequence, WrappedAsyncIterable, EmptyAsyncSequence, WrappedObjectAsync, WrappedArrayAsync, WrappedArrayLikeAsync, FunctionAsyncSequence, GeneratorAsyncSequence, RangeAsyncSequence, RepeatForeverAsyncSequence, RepeatAsyncSequence, AsyncSequenceMarker } from "./impl.js"; import { AsyncSequence } from "./types.js"; -export function asAsync(sequence: Sequence): AsyncSequence { +export function asAsync(sequence: Sequence>): AsyncSequence { return new WrappedSequence(sequence); } -export function wrap(iterable: MaybeAsyncIterable): AsyncSequence { +export function wrap(iterable: MaybeAsyncIterable>): AsyncSequence { if (isAsyncSequence(iterable)) { return iterable; } @@ -21,27 +21,29 @@ export function wrap(iterable: MaybeAsyncIterable): AsyncSequence { return asAsync(wrapSync(iterable)); } -export function sequence(iterable: AsyncIterable): AsyncSequence { +export function sequence(iterable: AsyncIterable>): AsyncSequence { return new WrappedAsyncIterable(iterable); } +export const EMPTY = new EmptyAsyncSequence(); + export function empty(): AsyncSequence { - return EmptyAsyncSequence.INSTANCE; + return EMPTY; } -export function single(obj: T | PromiseLike): AsyncSequence { +export function single(obj: MaybePromiseLike): AsyncSequence { return new WrappedObjectAsync(obj); } -export function array(array: (T | PromiseLike)[]): AsyncSequence { +export function array(array: MaybePromiseLike[]): AsyncSequence { return new WrappedArrayAsync(array); } -export function arrayLike(arrayLike: ArrayLike<(T | PromiseLike)>): AsyncSequence { +export function arrayLike(arrayLike: ArrayLike>): AsyncSequence { return new WrappedArrayLikeAsync(arrayLike); } -export function of(...elements: (T | PromiseLike)[]): AsyncSequence { +export function of(...elements: MaybePromiseLike[]): AsyncSequence { switch (elements.length) { case 0: return empty(); @@ -52,11 +54,11 @@ export function of(...elements: (T | PromiseLike)[]): AsyncSequence { } } -export function func(f: () => Promise): AsyncSequence { +export function func(f: () => MaybePromiseLike): AsyncSequence { return new FunctionAsyncSequence(f); } -export function generator(generator: () => AsyncGenerator): AsyncSequence { +export function generator(generator: () => MaybeAsyncGenerator>): AsyncSequence { return new GeneratorAsyncSequence(generator); } @@ -76,7 +78,7 @@ export function range(a: number, b?: number, c?: number): AsyncSequence return new RangeAsyncSequence(a, b, c); } -export function repeat(value: T, count?: number): AsyncSequence { +export function repeat(value: MaybePromiseLike, count?: number): AsyncSequence { if (count == undefined) { return new RepeatForeverAsyncSequence(value); } diff --git a/src/async/types.ts b/src/async/types.ts index 4a729b3..bfd949d 100644 --- a/src/async/types.ts +++ b/src/async/types.ts @@ -1,9 +1,9 @@ import { Collector } from "../collector/types.js"; import { AsyncRandomOptions } from "../random/types.js"; -import { MaybeAsyncPredicate, MaybeAsyncConverter, MaybeAsyncIterable, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, Predicate, MaybeAsyncAction } from "../types.js"; +import { MaybeAsyncPredicate, MaybeAsyncConverter, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybeAsyncSequence } from "../types.js"; -export interface AsyncSequence extends AsyncIterable> { - iterator(): AsyncIterator>; +export interface AsyncSequence extends AsyncIterable { + iterator(): AsyncIterator; apply(pipeline: (sequence: AsyncSequence) => TResult): TResult; @@ -13,22 +13,22 @@ export interface AsyncSequence extends AsyncIterable maxCount(): Promise; select(selector: MaybeAsyncConverter): AsyncSequence; - selectMany(selector: MaybeAsyncConverter>): AsyncSequence; + selectMany(selector: MaybeAsyncConverter>): AsyncSequence; where(predicate: MaybeAsyncPredicate): AsyncSequence; groupBy(keySelector: MaybeAsyncConverter, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater): AsyncSequence>; groupBy(keySelector: MaybeAsyncConverter, elementSelector: MaybeAsyncConverter, keyComparer?: MaybeAsyncEquater): AsyncSequence>; - join(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater): AsyncSequence<[Awaited, Awaited]>; - join(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, keyComparer?: MaybeAsyncEquater): AsyncSequence; + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater): AsyncSequence<[TElement, TOther]>; + join(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, keyComparer?: MaybeAsyncEquater): AsyncSequence; - groupJoin(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater): AsyncSequence>; - groupJoin(iterable: MaybeAsyncIterable, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, TResult>, keyComparer?: MaybeAsyncEquater): AsyncSequence; + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater): AsyncSequence>; + groupJoin(sequence: MaybeAsyncSequence, firstKeySelector: MaybeAsyncConverter, secondKeySelector: MaybeAsyncConverter, resultSelector: MaybeAsyncBiConverter, TResult>, keyComparer?: MaybeAsyncEquater): AsyncSequence; contains(obj: TElement, equater?: MaybeAsyncEquater): Promise; - sequenceEquals(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater): Promise; + sequenceEquals(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater): Promise; append(obj: TElement): AsyncSequence; @@ -36,7 +36,7 @@ export interface AsyncSequence extends AsyncIterable remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEquater): AsyncSequence; - concat(...iterables: MaybeAsyncIterable[]): AsyncSequence; + concat(...sequences: MaybeAsyncSequence[]): AsyncSequence; first(predicate?: MaybeAsyncPredicate): Promise; firstOrDefault(predicate?: MaybeAsyncPredicate, def?: TElement): Promise; @@ -66,25 +66,25 @@ export interface AsyncSequence extends AsyncIterable orderDescending(comparer?: MaybeAsyncComparer): AsyncSequence; orderByDescending(selector: MaybeAsyncConverter, comparer?: MaybeAsyncComparer): AsyncSequence; - partition(equater?: MaybeAsyncEquater): AsyncSequence[]>; - partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence[]>; + partition(equater?: MaybeAsyncEquater): AsyncSequence; + partitionBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; distinct(equater?: MaybeAsyncEquater): AsyncSequence; distinctBy(selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; - union(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater): AsyncSequence; - unionBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; + union(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater): AsyncSequence; + unionBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; - except(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater): AsyncSequence; - exceptBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; + except(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater): AsyncSequence; + exceptBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; - intersect(iterable: MaybeAsyncIterable, equater?: MaybeAsyncEquater): AsyncSequence; - intersectBy(iterable: MaybeAsyncIterable, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; + intersect(sequence: MaybeAsyncSequence, equater?: MaybeAsyncEquater): AsyncSequence; + intersectBy(sequence: MaybeAsyncSequence, selector: MaybeAsyncConverter, equater?: MaybeAsyncEquater): AsyncSequence; all(predicate: MaybeAsyncPredicate): Promise; any(predicate: MaybeAsyncPredicate): Promise; any(): Promise; - none(predicate: Predicate): Promise; + none(predicate: MaybeAsyncPredicate): Promise; none(): Promise; skip(n: number): AsyncSequence; @@ -99,9 +99,9 @@ export interface AsyncSequence extends AsyncIterable forEach(action: MaybeAsyncAction): Promise; - zip(iterable: MaybeAsyncIterable): AsyncSequence<[Awaited, Awaited]>; + zip(sequence: MaybeAsyncSequence): AsyncSequence<[TElement, TOther]>; - indexex(): AsyncSequence<[number, Awaited]>; + indexex(): AsyncSequence<[number, TElement]>; reversed(): AsyncSequence; @@ -111,6 +111,8 @@ export interface AsyncSequence extends AsyncIterable cached(): AsyncSequence; + asArray(): Promise; + toArray(): Promise; toMap(keySelector: MaybeAsyncConverter, valueSelector: MaybeAsyncConverter): Promise>; toSet(): Promise>; diff --git a/src/sync/impl.ts b/src/sync/impl.ts index 01155cd..74f351d 100644 --- a/src/sync/impl.ts +++ b/src/sync/impl.ts @@ -6,7 +6,7 @@ import { getRandomElement } from "../random/index.js"; import { RandomOptions } from "../random/types.js"; import { Converter, FilterPredicate, Equater, BiConverter, Predicate, Accumulator, Comparer, Action } from "../types.js"; import { strictEquals, identity, operatorCompare, reverseComparer, wrapAsIterable, defaultArrayComparer, combineComparers } from "../utils.js"; -import { array, empty, wrap } from "./index.js"; +import { array, empty } from "./index.js"; import { Sequence, GroupedSequence, OrderedSequence } from "./types.js"; export class SequenceMarker { } @@ -26,7 +26,7 @@ export abstract class BaseSequence extends SequenceMarker implements S return new SelectSequence(this, converter); } - selectMany(converter: Converter>): Sequence { + selectMany(converter: Converter>): Sequence { return new SelectManySequence(this, converter); } @@ -38,12 +38,12 @@ export abstract class BaseSequence extends SequenceMarker implements S return new GroupBySequence(this, keySelector, elementSelector, keyComparer); } - join(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, keyComparer?: Equater): Sequence { - return new JoinSequence(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer); + join(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, keyComparer?: Equater): Sequence { + return new JoinSequence(this, sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } - groupJoin(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, TResult>, keyComparer?: Equater): Sequence { - return new GroupJoinSequence(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer); + groupJoin(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, TResult>, keyComparer?: Equater): Sequence { + return new GroupJoinSequence(this, sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } contains(obj: TElement, equater?: Equater) { @@ -60,15 +60,13 @@ export abstract class BaseSequence extends SequenceMarker implements S return false; } - sequenceEquals(iterable: Iterable, equater?: Equater) { - if (this === iterable) { + sequenceEquals(sequence: Sequence, equater?: Equater) { + if (this === sequence) { return true; } - const that = wrap(iterable); - const thisCount = this.nonEnumeratedCount(); - const thatCount = that.nonEnumeratedCount(); + const thatCount = sequence.nonEnumeratedCount(); if (thisCount >= 0 && thatCount >= 0 && thisCount !== thatCount) { return false; @@ -79,7 +77,7 @@ export abstract class BaseSequence extends SequenceMarker implements S } const thisIterator = this.iterator(); - const thatIterator = that.iterator(); + const thatIterator = sequence.iterator(); while (true) { const thisNext = thisIterator.next(); @@ -111,15 +109,15 @@ export abstract class BaseSequence extends SequenceMarker implements S return new RemoveSequence(this, obj, all, equater); } - concat(...iterables: Iterable[]) { - if (iterables.length === 0) { + concat(...sequences: Sequence[]) { + if (sequences.length === 0) { return this; } const arr: Sequence[] = [this]; - for (const iterable of iterables) { - arr.push(wrap(iterable)); + for (const sequence of sequences) { + arr.push(sequence); } return new ConcatSequence(arr); @@ -470,28 +468,28 @@ export abstract class BaseSequence extends SequenceMarker implements S return new DistinctBySequence(this, selector, equater); } - union(iterable: Iterable, equater?: Equater): Sequence { - return new UnionSequence(this, wrap(iterable), equater); + union(sequence: Sequence, equater?: Equater): Sequence { + return new UnionSequence(this, sequence, equater); } - unionBy(iterable: Iterable, selector: Converter, equater?: Equater): Sequence { - return new UnionBySequence(this, wrap(iterable), selector, equater); + unionBy(sequence: Sequence, selector: Converter, equater?: Equater): Sequence { + return new UnionBySequence(this, sequence, selector, equater); } - except(iterable: Iterable): Sequence { - return new ExceptSequence(this, wrap(iterable)); + except(sequence: Sequence): Sequence { + return new ExceptSequence(this, sequence); } - exceptBy(iterable: Iterable, selector: Converter): Sequence { - return new ExceptBySequence(this, wrap(iterable), selector); + exceptBy(sequence: Sequence, selector: Converter): Sequence { + return new ExceptBySequence(this, sequence, selector); } - intersect(iterable: Iterable): Sequence { - return new IntersectSequence(this, wrap(iterable)); + intersect(sequence: Sequence): Sequence { + return new IntersectSequence(this, sequence); } - intersectBy(iterable: Iterable, selector: Converter): Sequence { - return new IntersectBySequence(this, wrap(iterable), selector); + intersectBy(sequence: Sequence, selector: Converter): Sequence { + return new IntersectBySequence(this, sequence, selector); } all(predicate: Predicate) { @@ -600,8 +598,8 @@ export abstract class BaseSequence extends SequenceMarker implements S } } - zip(iterable: Iterable): Sequence<[TElement, TOther]> { - return new ZippedSequence(this, wrap(iterable)); + zip(sequence: Sequence): Sequence<[TElement, TOther]> { + return new ZippedSequence(this, sequence); } indexed(): Sequence<[number, TElement]> { @@ -726,7 +724,7 @@ export class DelegatedSequence extends SequenceMarker implements Seque return this.#sequence.select(selector); } - selectMany(selector: Converter>) { + selectMany(selector: Converter>) { return this.#sequence.selectMany(selector); } @@ -734,27 +732,30 @@ export class DelegatedSequence extends SequenceMarker implements Seque return this.#sequence.where(predicate); } - groupBy(keySelector: Converter, elementSelector?: Converter, keyComparer?: Equater) { - //@ts-ignore + groupBy(keySelector: Converter, elementSelector?: undefined, keyComparer?: Equater | undefined): Sequence>; + groupBy(keySelector: Converter, elementSelector: Converter, keyComparer?: Equater | undefined): Sequence>; + groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) { return this.#sequence.groupBy(keySelector, elementSelector, keyComparer); } - join(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, keyComparer?: Equater) { - //@ts-ignore - return this.#sequence.join(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer); + join(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater | undefined): Sequence<[TElement, TOther]>; + join(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, keyComparer?: Equater | undefined): Sequence; + join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } - groupJoin(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: BiConverter, TResult>, keyComparer?: Equater) { - //@ts-ignore - return this.#sequence.groupJoin(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer); + groupJoin(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater | undefined): Sequence>; + groupJoin(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, TResult>, keyComparer?: Equater | undefined): Sequence; + groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) { + return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer); } contains(obj: TElement, equater?: Equater) { return this.#sequence.contains(obj, equater); } - sequenceEquals(iterable: Iterable, equater?: Equater) { - return this.#sequence.sequenceEquals(iterable, equater); + sequenceEquals(sequence: Sequence, equater?: Equater) { + return this.#sequence.sequenceEquals(sequence, equater); } append(obj: TElement) { @@ -769,8 +770,8 @@ export class DelegatedSequence extends SequenceMarker implements Seque return this.#sequence.remove(obj, all, equater); } - concat(...iterables: Iterable[]) { - return this.#sequence.concat(...iterables); + concat(...sequences: Sequence[]) { + return this.#sequence.concat(...sequences); } first(predicate?: Predicate) { @@ -857,41 +858,43 @@ export class DelegatedSequence extends SequenceMarker implements Seque return this.#sequence.distinctBy(selector, equater); } - union(iterable: Iterable, equater?: Equater) { - return this.#sequence.union(iterable, equater); + union(sequence: Sequence, equater?: Equater) { + return this.#sequence.union(sequence, equater); } - unionBy(iterable: Iterable, selector: Converter, equater?: Equater) { - return this.#sequence.unionBy(iterable, selector, equater); + unionBy(sequence: Sequence, selector: Converter, equater?: Equater) { + return this.#sequence.unionBy(sequence, selector, equater); } - except(iterable: Iterable, equater?: Equater) { - return this.#sequence.except(iterable, equater); + except(sequence: Sequence, equater?: Equater) { + return this.#sequence.except(sequence, equater); } - exceptBy(iterable: Iterable, selector: Converter, equater?: Equater) { - return this.#sequence.exceptBy(iterable, selector, equater); + exceptBy(sequence: Sequence, selector: Converter, equater?: Equater) { + return this.#sequence.exceptBy(sequence, selector, equater); } - intersect(iterable: Iterable, equater?: Equater) { - return this.#sequence.intersect(iterable, equater); + intersect(sequence: Sequence, equater?: Equater) { + return this.#sequence.intersect(sequence, equater); } - intersectBy(iterable: Iterable, selector: Converter, equater?: Equater) { - return this.#sequence.intersectBy(iterable, selector, equater); + intersectBy(sequence: Sequence, selector: Converter, equater?: Equater) { + return this.#sequence.intersectBy(sequence, selector, equater); } all(predicate: Predicate) { return this.#sequence.all(predicate); } - any(predicate?: Predicate) { - //@ts-ignore + any(predicate: Predicate): boolean; + any(): boolean; + any(predicate?: any) { return this.#sequence.any(predicate); } - none(predicate?: Predicate) { - //@ts-ignore + none(predicate: Predicate): boolean; + none(): boolean; + none(predicate?: any) { return this.#sequence.none(predicate); } @@ -927,8 +930,8 @@ export class DelegatedSequence extends SequenceMarker implements Seque this.#sequence.forEach(action); } - zip(iterable: Iterable) { - return this.#sequence.zip(iterable); + zip(sequence: Sequence) { + return this.#sequence.zip(sequence); } indexed() { @@ -951,6 +954,10 @@ export class DelegatedSequence extends SequenceMarker implements Seque return this.#sequence.cached(); } + // awaited(): AsyncSequence> { + // return this.#sequence.awaited(); + // } + asArray() { return this.#sequence.asArray(); } @@ -1053,16 +1060,10 @@ export abstract class BaseOrderedSequence extends BaseSequence extends BaseSequence { - static readonly INSTANCE = new EmptySequence(); - override nonEnumeratedCount() { return 0; } - override maxCount() { - return 0; - } - override *iterator() { } } @@ -1552,9 +1553,9 @@ class WhereSequence extends BaseSequence extends BaseSequence { readonly #sequence: Sequence; - readonly #converter: Converter>; + readonly #converter: Converter>; - constructor(sequence: Sequence, converter: Converter>) { + constructor(sequence: Sequence, converter: Converter>) { super(); this.#sequence = sequence; @@ -2479,3 +2480,17 @@ class PartitionBySequence extends BaseSequence { yield* partitions.values(); } } + +// class AwaitedSequence extends BaseAsyncSequence> { +// readonly #sequence: Sequence; + +// constructor(sequence: Sequence) { +// super(); + +// this.#sequence = sequence; +// } + +// override async *iterator() { +// yield* this.#sequence; +// } +// } diff --git a/src/sync/index.ts b/src/sync/index.ts index 8bb3658..a5844fa 100644 --- a/src/sync/index.ts +++ b/src/sync/index.ts @@ -27,8 +27,10 @@ export function sequence(iterable: Iterable): Sequence { return new WrappedIterable(iterable); } +export const EMPTY = new EmptySequence(); + export function empty(): Sequence { - return EmptySequence.INSTANCE; + return EMPTY; } export function single(obj: T): Sequence { diff --git a/src/sync/types.ts b/src/sync/types.ts index 98f58bf..c5de42e 100644 --- a/src/sync/types.ts +++ b/src/sync/types.ts @@ -13,7 +13,7 @@ export interface Sequence extends Iterable { maxCount(): number; select(selector: Converter): Sequence; - selectMany(selector: Converter>): Sequence; + selectMany(selector: Converter>): Sequence; where(predicate: FilterPredicate): Sequence; where(predicate: Predicate): Sequence; @@ -21,15 +21,15 @@ export interface Sequence extends Iterable { groupBy(keySelector: Converter, elementSelector?: undefined, keyComparer?: Equater): Sequence>; groupBy(keySelector: Converter, elementSelector: Converter, keyComparer?: Equater): Sequence>; - join(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater): Sequence<[TElement, TOther]>; - join(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, keyComparer?: Equater): Sequence; + join(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater): Sequence<[TElement, TOther]>; + join(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, keyComparer?: Equater): Sequence; - groupJoin(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater): Sequence>; - groupJoin(iterable: Iterable, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, TResult>, keyComparer?: Equater): Sequence; + groupJoin(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector?: undefined, keyComparer?: Equater): Sequence>; + groupJoin(sequence: Sequence, firstKeySelector: Converter, secondKeySelector: Converter, resultSelector: BiConverter, TResult>, keyComparer?: Equater): Sequence; contains(obj: TElement, equater?: Equater): boolean; - sequenceEquals(iterable: Iterable, equater?: Equater): boolean; + sequenceEquals(sequence: Sequence, equater?: Equater): boolean; append(obj: TElement): Sequence; @@ -37,7 +37,7 @@ export interface Sequence extends Iterable { remove(obj: TElement, all?: boolean, equater?: Equater): Sequence; - concat(...iterables: Iterable[]): Sequence; + concat(...sequences: Sequence[]): Sequence; first(predicate?: Predicate): TElement; firstOrDefault(predicate?: Predicate, def?: TElement): TElement | undefined; @@ -73,14 +73,14 @@ export interface Sequence extends Iterable { distinct(equater?: Equater): Sequence; distinctBy(selector: Converter, equater?: Equater): Sequence; - union(iterable: Iterable, equater?: Equater): Sequence; - unionBy(iterable: Iterable, selector: Converter, equater?: Equater): Sequence; + union(sequence: Sequence, equater?: Equater): Sequence; + unionBy(sequence: Sequence, selector: Converter, equater?: Equater): Sequence; - except(iterable: Iterable, equater?: Equater): Sequence; - exceptBy(iterable: Iterable, selector: Converter, equater?: Equater): Sequence; + except(sequence: Sequence, equater?: Equater): Sequence; + exceptBy(sequence: Sequence, selector: Converter, equater?: Equater): Sequence; - intersect(iterable: Iterable, equater?: Equater): Sequence; - intersectBy(iterable: Iterable, selector: Converter, equater?: Equater): Sequence; + intersect(sequence: Sequence, equater?: Equater): Sequence; + intersectBy(sequence: Sequence, selector: Converter, equater?: Equater): Sequence; all(predicate: Predicate): boolean; any(predicate: Predicate): boolean; @@ -100,7 +100,7 @@ export interface Sequence extends Iterable { forEach(action: Action): void; - zip(iterable: Iterable): Sequence<[TElement, TOther]>; + zip(sequence: Sequence): Sequence<[TElement, TOther]>; indexed(): Sequence<[number, TElement]>; @@ -112,6 +112,8 @@ export interface Sequence extends Iterable { cached(): Sequence; + // awaited(): AsyncSequence>; + asArray(): TElement[]; toArray(): TElement[]; toMap(keySelector: Converter, valueSelector: Converter): Map; diff --git a/src/types.ts b/src/types.ts index 9a0677a..11952ae 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,3 +1,6 @@ +import { AsyncSequence } from "./async/types.js"; +import { Sequence } from "./sync/types.js"; + export type Predicate = (obj: T) => boolean; export type FilterPredicate = (obj: TElement) => obj is TFiltered; export type Converter = (obj: TFrom) => TTo; @@ -9,10 +12,12 @@ export type Equater = (first: T, second: T) => boolean; export type MaybeAsyncIterable = Iterable | AsyncIterable; export type MaybeAsyncIterator = Iterator | AsyncIterator; - +export type MaybeAsyncGenerator = Generator | AsyncGenerator; export type AsyncFunction any> = TFunc extends (...args: infer P) => infer R ? (...args: P) => Promise> : never; export type MaybePromise = T | Promise; +export type MaybePromiseLike = T | PromiseLike; export type MaybeAsyncFunction any> = TFunc extends (...args: infer P) => infer R ? (...args: P) => MaybePromise : never; +export type MaybeAsyncSequence = Sequence | AsyncSequence; export type AsyncPredicate = AsyncFunction>; export type MaybeAsyncPredicate = MaybeAsyncFunction>;