harmonize sync and async implementations
This commit is contained in:
590
src/async.ts
590
src/async.ts
@@ -1,4 +1,4 @@
|
|||||||
import { Accumulator, Action, BiConverter, Comparer, Converter, Enumerable, Equater, Predicate, wrap as wrapSync } from "./sync.js";
|
import { Accumulator, Action, BiConverter, Comparer, Converter, Enumerable, Equater, Predicate } from "./sync.js";
|
||||||
import { AsyncFunction, MaybeAsyncFunction, MaybePromise, asAsyncGenerator, combineAsyncComparers, defaultArrayComparer, identity, isAsyncIterable, operatorCompare, strictEquals } from "./utils.js";
|
import { AsyncFunction, MaybeAsyncFunction, MaybePromise, asAsyncGenerator, combineAsyncComparers, defaultArrayComparer, identity, isAsyncIterable, operatorCompare, strictEquals } from "./utils.js";
|
||||||
import { createQueue } from "./queue.js";
|
import { createQueue } from "./queue.js";
|
||||||
import { selectionSorter } from "./sorting.js";
|
import { selectionSorter } from "./sorting.js";
|
||||||
@@ -33,11 +33,12 @@ export type MaybeAsyncEquater<T> = MaybeAsyncFunction<Equater<T>>;
|
|||||||
export interface AsyncEnumerable<TElement> extends AsyncIterable<TElement> {
|
export interface AsyncEnumerable<TElement> extends AsyncIterable<TElement> {
|
||||||
iterator(): AsyncIterator<TElement>;
|
iterator(): AsyncIterator<TElement>;
|
||||||
|
|
||||||
apply<TResult>(pipeline: (enumerable: this) => TResult): TResult;
|
apply<TResult>(pipeline: (enumerable: AsyncEnumerable<TElement>) => TResult): TResult;
|
||||||
|
|
||||||
count(predicate?: MaybeAsyncPredicate<TElement>): Promise<number>;
|
count(predicate?: MaybeAsyncPredicate<TElement>): Promise<number>;
|
||||||
nonEnumeratedCount(): Promise<number>;
|
nonEnumeratedCount(): Promise<number>;
|
||||||
fastCount(): Promise<number>;
|
fastCount(): Promise<number>;
|
||||||
|
maxCount(): Promise<number>;
|
||||||
|
|
||||||
select<TResult>(selector: MaybeAsyncConverter<TElement, TResult>): AsyncEnumerable<TResult>;
|
select<TResult>(selector: MaybeAsyncConverter<TElement, TResult>): AsyncEnumerable<TResult>;
|
||||||
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncIterable<TResult>>): AsyncEnumerable<TResult>;
|
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncIterable<TResult>>): AsyncEnumerable<TResult>;
|
||||||
@@ -55,7 +56,7 @@ export interface AsyncEnumerable<TElement> extends AsyncIterable<TElement> {
|
|||||||
|
|
||||||
contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
||||||
|
|
||||||
sequenceEqual(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
sequenceEquals(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
||||||
|
|
||||||
append(obj: TElement): AsyncEnumerable<TElement>;
|
append(obj: TElement): AsyncEnumerable<TElement>;
|
||||||
|
|
||||||
@@ -108,6 +109,8 @@ export interface AsyncEnumerable<TElement> extends AsyncIterable<TElement> {
|
|||||||
all(predicate: MaybeAsyncPredicate<TElement>): Promise<boolean>;
|
all(predicate: MaybeAsyncPredicate<TElement>): Promise<boolean>;
|
||||||
any(predicate: MaybeAsyncPredicate<TElement>): Promise<boolean>;
|
any(predicate: MaybeAsyncPredicate<TElement>): Promise<boolean>;
|
||||||
any(): Promise<boolean>;
|
any(): Promise<boolean>;
|
||||||
|
none(predicate: Predicate<TElement>): Promise<boolean>;
|
||||||
|
none(): Promise<boolean>;
|
||||||
|
|
||||||
skip(n: number): AsyncEnumerable<TElement>;
|
skip(n: number): AsyncEnumerable<TElement>;
|
||||||
skipLast(n: number): AsyncEnumerable<TElement>;
|
skipLast(n: number): AsyncEnumerable<TElement>;
|
||||||
@@ -123,18 +126,21 @@ export interface AsyncEnumerable<TElement> extends AsyncIterable<TElement> {
|
|||||||
|
|
||||||
zip<TOther>(iterable: MaybeAsyncIterable<TOther>): AsyncEnumerable<[TElement, TOther]>;
|
zip<TOther>(iterable: MaybeAsyncIterable<TOther>): AsyncEnumerable<[TElement, TOther]>;
|
||||||
|
|
||||||
index(): AsyncEnumerable<[number, TElement]>;
|
indexex(): AsyncEnumerable<[number, TElement]>;
|
||||||
|
|
||||||
reverse(): AsyncEnumerable<TElement>;
|
reversed(): AsyncEnumerable<TElement>;
|
||||||
|
|
||||||
chunk(size: number): AsyncEnumerable<TElement[]>;
|
chunked(size: number): AsyncEnumerable<TElement[]>;
|
||||||
|
|
||||||
cache(): AsyncEnumerable<TElement>;
|
// random(options?: RandomOptions<TElement>): TElement | undefined;
|
||||||
|
|
||||||
|
cached(): AsyncEnumerable<TElement>;
|
||||||
|
|
||||||
|
asArray(): Promise<TElement[]>;
|
||||||
toArray(): Promise<TElement[]>;
|
toArray(): Promise<TElement[]>;
|
||||||
toMap<TKey, TValue>(keySelector: MaybeAsyncConverter<TElement, TKey>, valueSelector: MaybeAsyncConverter<TElement, TValue>): Promise<Map<TKey, TValue>>;
|
toMap<TKey, TValue>(keySelector: MaybeAsyncConverter<TElement, TKey>, valueSelector: MaybeAsyncConverter<TElement, TValue>): Promise<Map<TKey, TValue>>;
|
||||||
toSet(): Promise<Set<TElement>>;
|
toSet(): Promise<Set<TElement>>;
|
||||||
toObject<TValue>(keySelector: MaybeAsyncConverter<TElement, PropertyKey>, valueSelector: MaybeAsyncConverter<TElement, TValue>): Promise<Record<PropertyKey, TValue>>;
|
toObject<TKey extends PropertyKey, TValue>(keySelector: MaybeAsyncConverter<TElement, TKey>, valueSelector: MaybeAsyncConverter<TElement, TValue>): Promise<Record<TKey, TValue>>;
|
||||||
|
|
||||||
collect<TResult>(collector: Collector<TElement, any, TResult>): Promise<TResult>;
|
collect<TResult>(collector: Collector<TElement, any, TResult>): Promise<TResult>;
|
||||||
}
|
}
|
||||||
@@ -159,116 +165,100 @@ export interface OrderedAsyncEnumerable<TElement> extends AsyncEnumerable<TEleme
|
|||||||
|
|
||||||
//#region wrappers
|
//#region wrappers
|
||||||
|
|
||||||
export function asAsync<T>(enumerable: Enumerable<T>): AsyncEnumerable<T> {
|
export namespace AsyncEnumerable {
|
||||||
return new WrappedEnumerable(enumerable);
|
export function asAsync<T>(enumerable: Enumerable<T>): AsyncEnumerable<T> {
|
||||||
}
|
return new WrappedEnumerable(enumerable);
|
||||||
|
|
||||||
export function wrap<T>(iterable: MaybeAsyncIterable<T>): AsyncEnumerable<T> {
|
|
||||||
if (iterable instanceof BaseAsyncEnumerable) {
|
|
||||||
return iterable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAsyncIterable(iterable)) {
|
export function wrap<T>(iterable: MaybeAsyncIterable<T>): AsyncEnumerable<T> {
|
||||||
return sequence(iterable);
|
if (iterable instanceof BaseAsyncEnumerable) {
|
||||||
|
return iterable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAsyncIterable(iterable)) {
|
||||||
|
return sequence(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
return asAsync(Enumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
return asAsync(wrapSync(iterable));
|
export function sequence<T>(iterable: AsyncIterable<T>): AsyncEnumerable<T> {
|
||||||
}
|
return new WrappedAsyncIterable(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
export function sequence<T>(iterable: AsyncIterable<T>): AsyncEnumerable<T> {
|
export function empty<T>(): AsyncEnumerable<T> {
|
||||||
return new WrappedAsyncIterable(iterable);
|
return EmptyAsyncEnumerable.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function empty<T>(): AsyncEnumerable<T> {
|
export function single<T>(obj: T): AsyncEnumerable<T> {
|
||||||
return EmptyAsyncEnumerable.INSTANCE;
|
return new WrappedObjectAsync(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function single<T>(obj: T): AsyncEnumerable<T> {
|
export function array<T>(array: T[]): AsyncEnumerable<T> {
|
||||||
return new WrappedObjectAsync(obj);
|
return new WrappedArrayAsync(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function array<T>(array: T[]): AsyncEnumerable<T> {
|
export function arrayLike<T>(arrayLike: ArrayLike<T>): AsyncEnumerable<T> {
|
||||||
return new WrappedArrayAsync(array);
|
return new WrappedArrayLikeAsync(arrayLike);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function arrayLike<T>(arrayLike: ArrayLike<T>): AsyncEnumerable<T> {
|
export function of<T>(...elements: T[]): AsyncEnumerable<T> {
|
||||||
return new WrappedArrayLikeAsync(arrayLike);
|
switch (elements.length) {
|
||||||
}
|
case 0:
|
||||||
|
return empty();
|
||||||
|
case 1:
|
||||||
|
return single(elements[0]);
|
||||||
|
default:
|
||||||
|
return array(elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function of<T>(...elements: T[]): AsyncEnumerable<T> {
|
export function func<T>(f: () => Promise<T>): AsyncEnumerable<T> {
|
||||||
switch (elements.length) {
|
return new FunctionAsyncEnumerable(f);
|
||||||
case 0:
|
}
|
||||||
|
|
||||||
|
export function generator<T>(generator: () => AsyncGenerator<T>): AsyncEnumerable<T> {
|
||||||
|
return new GeneratorAsyncEnumerable(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function range(max: number): AsyncEnumerable<number>
|
||||||
|
export function range(min: number, max: number): AsyncEnumerable<number>
|
||||||
|
export function range(min: number, max: number, step: number): AsyncEnumerable<number>
|
||||||
|
export function range(a: number, b?: number, c?: number): AsyncEnumerable<number> {
|
||||||
|
if (b === undefined) {
|
||||||
|
b = a;
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c === undefined) {
|
||||||
|
c = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RangeAsyncEnumerable(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function repeat<T>(value: T, count?: number): AsyncEnumerable<T> {
|
||||||
|
if (count == undefined) {
|
||||||
|
return new RepeatForeverAsyncEnumerable(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
throw new RangeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
return empty();
|
return empty();
|
||||||
case 1:
|
|
||||||
return single(elements[0]);
|
|
||||||
default:
|
|
||||||
return array(elements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function func<T>(f: () => Promise<T>): AsyncEnumerable<T> {
|
|
||||||
return new FunctionAsyncEnumerable(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generator<T>(generator: () => AsyncGenerator<T>): AsyncEnumerable<T> {
|
|
||||||
return new GeneratorAsyncEnumerable(generator);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function range(max: number): AsyncEnumerable<number>
|
|
||||||
export function range(min: number, max: number): AsyncEnumerable<number>
|
|
||||||
export function range(min: number, max: number, step: number): AsyncEnumerable<number>
|
|
||||||
export function range(a: number, b?: number, c?: number): AsyncEnumerable<number> {
|
|
||||||
if (b === undefined) {
|
|
||||||
b = a;
|
|
||||||
a = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (c === undefined) {
|
|
||||||
c = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RangeAsyncEnumerable(a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function repeat<T>(value: T, count?: number): AsyncEnumerable<T> {
|
|
||||||
if (count == undefined) {
|
|
||||||
return new RepeatForeverAsyncEnumerable(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 0) {
|
|
||||||
throw new RangeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 0) {
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 1) {
|
|
||||||
return new WrappedObjectAsync(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RepeatAsyncEnumerable(value, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
export namespace sum {
|
|
||||||
export async function number(iterable: AsyncIterable<number>) {
|
|
||||||
let result = 0;
|
|
||||||
|
|
||||||
for await (const n of iterable) {
|
|
||||||
result += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
if (count === 1) {
|
||||||
}
|
return new WrappedObjectAsync(value);
|
||||||
|
|
||||||
export async function bigint(iterable: AsyncIterable<bigint>) {
|
|
||||||
let result = 0n;
|
|
||||||
|
|
||||||
for await (const n of iterable) {
|
|
||||||
result += n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return new RepeatAsyncEnumerable(value, count);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isAsyncEnumerable<T = any>(obj: any): obj is Enumerable<T> {
|
||||||
|
return obj instanceof AsyncEnumerableMarker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -276,14 +266,18 @@ export namespace sum {
|
|||||||
|
|
||||||
//#region implementations
|
//#region implementations
|
||||||
|
|
||||||
export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<TElement> {
|
class AsyncEnumerableMarker {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class BaseAsyncEnumerable<TElement> extends AsyncEnumerableMarker implements AsyncEnumerable<TElement> {
|
||||||
[Symbol.asyncIterator]() {
|
[Symbol.asyncIterator]() {
|
||||||
return this.iterator();
|
return this.iterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract iterator(): AsyncIterator<TElement>;
|
abstract iterator(): AsyncIterator<TElement>;
|
||||||
|
|
||||||
apply<TResult>(pipeline: (enumerable: this) => TResult) {
|
apply<TResult>(pipeline: (enumerable: AsyncEnumerable<TElement>) => TResult): TResult {
|
||||||
return pipeline(this);
|
return pipeline(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -304,11 +298,11 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
}
|
}
|
||||||
|
|
||||||
join<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncEnumerable<TResult> {
|
join<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncEnumerable<TResult> {
|
||||||
return new JoinAsyncEnumerable<TElement, TOther, TKey, TResult>(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
return new JoinAsyncEnumerable<TElement, TOther, TKey, TResult>(this, AsyncEnumerable.wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupJoin<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: MaybeAsyncBiConverter<TElement, AsyncEnumerable<TOther>, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncEnumerable<TResult> {
|
groupJoin<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: MaybeAsyncBiConverter<TElement, AsyncEnumerable<TOther>, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncEnumerable<TResult> {
|
||||||
return new GroupJoinAsyncEnumerable<TElement, TOther, TKey, TResult>(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
return new GroupJoinAsyncEnumerable<TElement, TOther, TKey, TResult>(this, AsyncEnumerable.wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
async contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>) {
|
async contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>) {
|
||||||
@@ -325,12 +319,12 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
async sequenceEqual(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>) {
|
async sequenceEquals(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>) {
|
||||||
if (this === iterable) {
|
if (this === iterable) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const that = wrap(iterable);
|
const that = AsyncEnumerable.wrap(iterable);
|
||||||
|
|
||||||
const thisCount = await this.nonEnumeratedCount();
|
const thisCount = await this.nonEnumeratedCount();
|
||||||
const thatCount = await that.nonEnumeratedCount();
|
const thatCount = await that.nonEnumeratedCount();
|
||||||
@@ -351,7 +345,7 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
const thatNext = await thatIterator.next();
|
const thatNext = await thatIterator.next();
|
||||||
|
|
||||||
if (thisNext.done) {
|
if (thisNext.done) {
|
||||||
return thatNext.done === true; // no undefined!
|
return thatNext.done === true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (thatNext.done) {
|
if (thatNext.done) {
|
||||||
@@ -384,7 +378,7 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
const arr: AsyncEnumerable<TElement>[] = [this];
|
const arr: AsyncEnumerable<TElement>[] = [this];
|
||||||
|
|
||||||
for (const iterable of iterables) {
|
for (const iterable of iterables) {
|
||||||
arr.push(wrap(iterable));
|
arr.push(AsyncEnumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConcatAsyncEnumerable(arr);
|
return new ConcatAsyncEnumerable(arr);
|
||||||
@@ -419,6 +413,11 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
return n >= 0 ? n : await this.count();
|
return n >= 0 ? n : await this.count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async maxCount() {
|
||||||
|
const n = await this.nonEnumeratedCount();
|
||||||
|
return n >= 0 ? n : Infinity;
|
||||||
|
}
|
||||||
|
|
||||||
async #tryGetFirst(predicate?: MaybeAsyncPredicate<TElement>) {
|
async #tryGetFirst(predicate?: MaybeAsyncPredicate<TElement>) {
|
||||||
if (predicate) {
|
if (predicate) {
|
||||||
for await (const element of this) {
|
for await (const element of this) {
|
||||||
@@ -723,27 +722,27 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
}
|
}
|
||||||
|
|
||||||
union(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncEnumerable<TElement> {
|
union(iterable: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncEnumerable<TElement> {
|
||||||
return new UnionAsyncEnumerable<TElement>(this, wrap(iterable), equater);
|
return new UnionAsyncEnumerable<TElement>(this, AsyncEnumerable.wrap(iterable), equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
unionBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncEnumerable<TElement> {
|
unionBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncEnumerable<TElement> {
|
||||||
return new UnionByAsyncEnumerable<TElement, TBy>(this, wrap(iterable), selector, equater);
|
return new UnionByAsyncEnumerable<TElement, TBy>(this, AsyncEnumerable.wrap(iterable), selector, equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
except(iterable: MaybeAsyncIterable<TElement>): AsyncEnumerable<TElement> {
|
except(iterable: MaybeAsyncIterable<TElement>): AsyncEnumerable<TElement> {
|
||||||
return new ExceptAsyncEnumerable<TElement>(this, wrap(iterable));
|
return new ExceptAsyncEnumerable<TElement>(this, AsyncEnumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
exceptBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncEnumerable<TElement> {
|
exceptBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncEnumerable<TElement> {
|
||||||
return new ExceptByAsyncEnumerable<TElement, TBy>(this, wrap(iterable), selector);
|
return new ExceptByAsyncEnumerable<TElement, TBy>(this, AsyncEnumerable.wrap(iterable), selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
intersect(iterable: MaybeAsyncIterable<TElement>): AsyncEnumerable<TElement> {
|
intersect(iterable: MaybeAsyncIterable<TElement>): AsyncEnumerable<TElement> {
|
||||||
return new IntersectAsyncEnumerable<TElement>(this, wrap(iterable));
|
return new IntersectAsyncEnumerable<TElement>(this, AsyncEnumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
intersectBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncEnumerable<TElement> {
|
intersectBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncEnumerable<TElement> {
|
||||||
return new IntersectByAsyncEnumerable<TElement, TBy>(this, wrap(iterable), selector);
|
return new IntersectByAsyncEnumerable<TElement, TBy>(this, AsyncEnumerable.wrap(iterable), selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
async all(predicate: MaybeAsyncPredicate<TElement>) {
|
async all(predicate: MaybeAsyncPredicate<TElement>) {
|
||||||
@@ -782,6 +781,26 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
return n < 0 ? !(await this.iterator().next()).done : n > 0;
|
return n < 0 ? !(await this.iterator().next()).done : n > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async none(predicate?: MaybeAsyncPredicate<TElement>) {
|
||||||
|
const n = await this.nonEnumeratedCount();
|
||||||
|
|
||||||
|
if (n === 0) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (predicate) {
|
||||||
|
for await (const element of this) {
|
||||||
|
if (predicate(element)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return n < 0 && (await this.iterator().next()).done === true;
|
||||||
|
}
|
||||||
|
|
||||||
skip(n: number): AsyncEnumerable<TElement> {
|
skip(n: number): AsyncEnumerable<TElement> {
|
||||||
if (n < 0) {
|
if (n < 0) {
|
||||||
throw new Error("Cannot skip a negative number of elements.");
|
throw new Error("Cannot skip a negative number of elements.");
|
||||||
@@ -807,7 +826,7 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
throw new Error("Cannot take a negative number of elements.");
|
throw new Error("Cannot take a negative number of elements.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return n === 0 ? empty<TElement>() : new TakeAsyncEnumerable<TElement>(this, n);
|
return n === 0 ? AsyncEnumerable.empty<TElement>() : new TakeAsyncEnumerable<TElement>(this, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
takeLast(n: number): AsyncEnumerable<TElement> {
|
takeLast(n: number): AsyncEnumerable<TElement> {
|
||||||
@@ -815,7 +834,7 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
throw new Error("Cannot take a negative number of elements.");
|
throw new Error("Cannot take a negative number of elements.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return n === 0 ? empty<TElement>() : new TakeLastAsyncEnumerable<TElement>(this, n);
|
return n === 0 ? AsyncEnumerable.empty<TElement>() : new TakeLastAsyncEnumerable<TElement>(this, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
takeWhile(predicate: MaybeAsyncPredicate<TElement>): AsyncEnumerable<TElement> {
|
takeWhile(predicate: MaybeAsyncPredicate<TElement>): AsyncEnumerable<TElement> {
|
||||||
@@ -833,18 +852,18 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
}
|
}
|
||||||
|
|
||||||
zip<TOther>(iterable: MaybeAsyncIterable<TOther>): AsyncEnumerable<[TElement, TOther]> {
|
zip<TOther>(iterable: MaybeAsyncIterable<TOther>): AsyncEnumerable<[TElement, TOther]> {
|
||||||
return new ZippedAsyncEnumerable<TElement, TOther>(this, wrap(iterable));
|
return new ZippedAsyncEnumerable<TElement, TOther>(this, AsyncEnumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
index(): AsyncEnumerable<[number, TElement]> {
|
indexex(): AsyncEnumerable<[number, TElement]> {
|
||||||
return new IndexedAsyncEnumerable<TElement>(this);
|
return new IndexedAsyncEnumerable<TElement>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
reverse(): AsyncEnumerable<TElement> {
|
reversed(): AsyncEnumerable<TElement> {
|
||||||
return new ReversedAsyncEnumerable<TElement>(this);
|
return new ReversedAsyncEnumerable<TElement>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
chunk(size: number): AsyncEnumerable<TElement[]> {
|
chunked(size: number): AsyncEnumerable<TElement[]> {
|
||||||
if (size <= 0) {
|
if (size <= 0) {
|
||||||
throw new Error("Chunk size must be positive.");
|
throw new Error("Chunk size must be positive.");
|
||||||
}
|
}
|
||||||
@@ -852,10 +871,14 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
return new ChunkedAsyncEnumerable<TElement>(this, size);
|
return new ChunkedAsyncEnumerable<TElement>(this, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
cache(): AsyncEnumerable<TElement> {
|
cached(): AsyncEnumerable<TElement> {
|
||||||
return new CacheAsyncEnumerable<TElement>(this);
|
return new CacheAsyncEnumerable<TElement>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async asArray() {
|
||||||
|
return await this.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
async toArray() {
|
async toArray() {
|
||||||
const array: TElement[] = [];
|
const array: TElement[] = [];
|
||||||
|
|
||||||
@@ -913,28 +936,313 @@ export abstract class BaseAsyncEnumerable<TElement> implements AsyncEnumerable<T
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GroupedAsyncEnumerableImpl<TElement, TKey> extends BaseAsyncEnumerable<TElement> implements GroupedAsyncEnumerable<TKey, TElement> {
|
class DelegatedAsyncEnumerable<TElement> extends AsyncEnumerableMarker implements AsyncEnumerable<TElement> {
|
||||||
readonly #key: TKey;
|
#enumerable: AsyncEnumerable<TElement>;
|
||||||
readonly #grouping: AsyncEnumerable<TElement>;
|
|
||||||
|
|
||||||
constructor(key: TKey, grouping: AsyncEnumerable<TElement>) {
|
constructor(enumerable: AsyncEnumerable<TElement>) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.#enumerable = enumerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
get enumerable() {
|
||||||
|
return this.#enumerable;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected set enumerable(value: AsyncEnumerable<TElement>) {
|
||||||
|
this.#enumerable = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Symbol.asyncIterator]() {
|
||||||
|
return this.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator() {
|
||||||
|
return this.#enumerable.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
|
apply<TResult>(pipeline: (enumerable: AsyncEnumerable<TElement>) => TResult) {
|
||||||
|
return this.#enumerable.apply(pipeline);
|
||||||
|
}
|
||||||
|
|
||||||
|
count(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined): Promise<number> {
|
||||||
|
return this.#enumerable.count(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
nonEnumeratedCount(): Promise<number> {
|
||||||
|
return this.#enumerable.nonEnumeratedCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
fastCount(): Promise<number> {
|
||||||
|
return this.#enumerable.fastCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
maxCount(): Promise<number> {
|
||||||
|
return this.#enumerable.maxCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
select<TResult>(selector: (obj: TElement) => MaybePromise<TResult>): AsyncEnumerable<TResult> {
|
||||||
|
return this.#enumerable.select(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
selectMany<TResult>(selector: (obj: TElement) => MaybePromise<MaybeAsyncIterable<TResult>>): AsyncEnumerable<TResult> {
|
||||||
|
return this.#enumerable.selectMany(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
where(predicate: (obj: TElement) => MaybePromise<boolean>): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.where(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupBy<TKey>(keySelector: (obj: TElement) => MaybePromise<TKey>, elementSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<GroupedAsyncEnumerable<TKey, TElement>>;
|
||||||
|
groupBy<TKey, TResult>(keySelector: (obj: TElement) => MaybePromise<TKey>, elementSelector: (obj: TElement) => MaybePromise<TResult>, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<GroupedAsyncEnumerable<TKey, TResult>>;
|
||||||
|
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
|
||||||
|
return this.#enumerable.groupBy(keySelector, elementSelector, keyComparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
join<TOther, TKey>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: (obj: TElement) => MaybePromise<TKey>, secondKeySelector: (obj: TOther) => MaybePromise<TKey>, resultSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<[TElement, TOther]>;
|
||||||
|
join<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: (obj: TElement) => MaybePromise<TKey>, secondKeySelector: (obj: TOther) => MaybePromise<TKey>, resultSelector: (first: TElement, second: TOther) => MaybePromise<TResult>, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TResult>;
|
||||||
|
join(iterable: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||||
|
return this.#enumerable.join(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupJoin<TOther, TKey>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: (obj: TElement) => MaybePromise<TKey>, secondKeySelector: (obj: TOther) => MaybePromise<TKey>, resultSelector?: undefined, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<GroupedAsyncEnumerable<TElement, TOther>>;
|
||||||
|
groupJoin<TOther, TKey, TResult>(iterable: MaybeAsyncIterable<TOther>, firstKeySelector: (obj: TElement) => MaybePromise<TKey>, secondKeySelector: (obj: TOther) => MaybePromise<TKey>, resultSelector: (first: TElement, second: AsyncEnumerable<TOther>) => MaybePromise<TResult>, keyComparer?: ((first: TKey, second: TKey) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TResult>;
|
||||||
|
groupJoin(iterable: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||||
|
return this.#enumerable.groupJoin(iterable, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
contains(obj: TElement, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): Promise<boolean> {
|
||||||
|
return this.#enumerable.contains(obj, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
sequenceEquals(iterable: MaybeAsyncIterable<TElement>, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): Promise<boolean> {
|
||||||
|
return this.#enumerable.sequenceEquals(iterable, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
append(obj: TElement): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.append(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
prepend(obj: TElement): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.prepend(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
remove(obj: TElement, all?: boolean | undefined, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.remove(obj, all, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
concat(...iterables: MaybeAsyncIterable<TElement>[]): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.concat(...iterables);
|
||||||
|
}
|
||||||
|
|
||||||
|
first(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined): Promise<TElement> {
|
||||||
|
return this.#enumerable.first(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
firstOrDefault(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined, def?: TElement | undefined): Promise<TElement | undefined> {
|
||||||
|
return this.#enumerable.firstOrDefault(predicate, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
last(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined): Promise<TElement> {
|
||||||
|
return this.#enumerable.last(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
lastOrDefault(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined, def?: TElement | undefined): Promise<TElement | undefined> {
|
||||||
|
return this.#enumerable.lastOrDefault(predicate, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
single(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined): Promise<TElement> {
|
||||||
|
return this.#enumerable.single(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
singleOrDefault(predicate?: ((obj: TElement) => MaybePromise<boolean>) | undefined, def?: TElement | undefined): Promise<TElement | undefined> {
|
||||||
|
return this.#enumerable.singleOrDefault(predicate, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
elementAt(index: number): Promise<TElement> {
|
||||||
|
return this.#enumerable.elementAt(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
elementAtOrDefault(index: number, def?: TElement | undefined): Promise<TElement | undefined> {
|
||||||
|
return this.#enumerable.elementAtOrDefault(index, def);
|
||||||
|
}
|
||||||
|
|
||||||
|
aggregate(accumulator: (acc: TElement, obj: TElement) => MaybePromise<TElement>): Promise<TElement>;
|
||||||
|
aggregate<TAccumulator>(accumulator: (acc: TAccumulator, obj: TElement) => MaybePromise<TAccumulator>, seed?: TAccumulator | undefined): Promise<TAccumulator>;
|
||||||
|
aggregate<TAccumulator, TResult>(accumulator: (acc: TAccumulator, obj: TElement) => MaybePromise<TAccumulator>, seed?: TAccumulator | undefined, resultSelector?: ((obj: TAccumulator) => MaybePromise<TResult>) | undefined): Promise<TResult>;
|
||||||
|
aggregate(accumulator: any, seed?: any, resultSelector?: any) {
|
||||||
|
return this.#enumerable.aggregate(accumulator, seed, resultSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
min(): Promise<TElement> {
|
||||||
|
return this.#enumerable.min();
|
||||||
|
}
|
||||||
|
|
||||||
|
minBy<TBy>(selector: (obj: TElement) => MaybePromise<TBy>): Promise<TElement> {
|
||||||
|
return this.#enumerable.minBy(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
max(): Promise<TElement> {
|
||||||
|
return this.#enumerable.max();
|
||||||
|
}
|
||||||
|
|
||||||
|
maxBy<TBy>(selector: (obj: TElement) => MaybePromise<TBy>): Promise<TElement> {
|
||||||
|
return this.#enumerable.maxBy(selector);
|
||||||
|
}
|
||||||
|
|
||||||
|
order(comparer?: ((first: TElement, second: TElement) => MaybePromise<number>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.order(comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
orderBy<TBy>(selector: (obj: TElement) => MaybePromise<TBy>, comparer?: ((first: TBy, second: TBy) => MaybePromise<number>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.orderBy(selector, comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
orderDescending(comparer?: ((first: TElement, second: TElement) => MaybePromise<number>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.orderDescending(comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
orderByDescending<TBy>(selector: (obj: TElement) => MaybePromise<TBy>, comparer?: ((first: TBy, second: TBy) => MaybePromise<number>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.orderByDescending(selector, comparer);
|
||||||
|
}
|
||||||
|
|
||||||
|
distinct(equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.distinct(equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
distinctBy<TBy>(selector: (obj: TElement) => MaybePromise<TBy>, equater?: ((first: TBy, second: TBy) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.distinctBy(selector, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
union(iterable: MaybeAsyncIterable<TElement>, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.union(iterable, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
unionBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: (obj: TElement) => MaybePromise<TBy>, equater?: ((first: TBy, second: TBy) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.unionBy(iterable, selector, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
except(iterable: MaybeAsyncIterable<TElement>, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.except(iterable, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
exceptBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: (obj: TElement) => MaybePromise<TBy>, equater?: ((first: TBy, second: TBy) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.exceptBy(iterable, selector, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
intersect(iterable: MaybeAsyncIterable<TElement>, equater?: ((first: TElement, second: TElement) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.intersect(iterable, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
intersectBy<TBy>(iterable: MaybeAsyncIterable<TElement>, selector: (obj: TElement) => MaybePromise<TBy>, equater?: ((first: TBy, second: TBy) => MaybePromise<boolean>) | undefined): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.intersectBy(iterable, selector, equater);
|
||||||
|
}
|
||||||
|
|
||||||
|
all(predicate: (obj: TElement) => MaybePromise<boolean>): Promise<boolean> {
|
||||||
|
return this.#enumerable.all(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
any(predicate: (obj: TElement) => MaybePromise<boolean>): Promise<boolean>;
|
||||||
|
any(): Promise<boolean>;
|
||||||
|
any(predicate?: any) {
|
||||||
|
return this.#enumerable.any(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
none(predicate: Predicate<TElement>): Promise<boolean>;
|
||||||
|
none(): Promise<boolean>;
|
||||||
|
none(predicate?: any) {
|
||||||
|
return this.#enumerable.none(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
skip(n: number): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.skip(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
skipLast(n: number): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.skipLast(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
skipWhile(condition: (obj: TElement) => MaybePromise<boolean>): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.skipWhile(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
take(n: number): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.take(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
takeLast(n: number): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.takeLast(n);
|
||||||
|
}
|
||||||
|
|
||||||
|
takeWhile(condition: (obj: TElement) => MaybePromise<boolean>): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.takeWhile(condition);
|
||||||
|
}
|
||||||
|
|
||||||
|
peek(action: (obj: TElement) => MaybePromise<void>): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.peek(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
forEach(action: (obj: TElement) => MaybePromise<void>): Promise<void> {
|
||||||
|
return this.#enumerable.forEach(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
zip<TOther>(iterable: MaybeAsyncIterable<TOther>): AsyncEnumerable<[TElement, TOther]> {
|
||||||
|
return this.#enumerable.zip(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
indexex(): AsyncEnumerable<[number, TElement]> {
|
||||||
|
return this.#enumerable.indexex();
|
||||||
|
}
|
||||||
|
|
||||||
|
reversed(): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.reversed();
|
||||||
|
}
|
||||||
|
|
||||||
|
chunked(size: number): AsyncEnumerable<TElement[]> {
|
||||||
|
return this.#enumerable.chunked(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
cached(): AsyncEnumerable<TElement> {
|
||||||
|
return this.#enumerable.cached();
|
||||||
|
}
|
||||||
|
|
||||||
|
asArray(): Promise<TElement[]> {
|
||||||
|
return this.#enumerable.asArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
toArray(): Promise<TElement[]> {
|
||||||
|
return this.#enumerable.toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
toMap<TKey, TValue>(keySelector: (obj: TElement) => MaybePromise<TKey>, valueSelector: (obj: TElement) => MaybePromise<TValue>): Promise<Map<TKey, TValue>> {
|
||||||
|
return this.#enumerable.toMap(keySelector, valueSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
toSet(): Promise<Set<TElement>> {
|
||||||
|
return this.#enumerable.toSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
toObject<TValue>(keySelector: (obj: TElement) => MaybePromise<PropertyKey>, valueSelector: (obj: TElement) => MaybePromise<TValue>): Promise<Record<PropertyKey, TValue>> {
|
||||||
|
return this.#enumerable.toObject(keySelector, valueSelector);
|
||||||
|
}
|
||||||
|
|
||||||
|
collect<TResult>(collector: Collector<TElement, any, TResult>): Promise<TResult> {
|
||||||
|
return this.#enumerable.collect(collector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupedAsyncEnumerableImpl<TElement, TKey> extends DelegatedAsyncEnumerable<TElement> implements GroupedAsyncEnumerable<TKey, TElement> {
|
||||||
|
readonly #key: TKey;
|
||||||
|
|
||||||
|
constructor(key: TKey, grouping: AsyncEnumerable<TElement>) {
|
||||||
|
super(grouping);
|
||||||
|
|
||||||
this.#key = key;
|
this.#key = key;
|
||||||
this.#grouping = grouping;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public get key() {
|
public get key() {
|
||||||
return this.#key;
|
return this.#key;
|
||||||
}
|
}
|
||||||
|
|
||||||
override async nonEnumeratedCount() {
|
|
||||||
return await this.#grouping.nonEnumeratedCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
override iterator() {
|
|
||||||
return this.#grouping.iterator();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class BaseOrderedAsyncEnumerable<TElement> extends BaseAsyncEnumerable<TElement> implements OrderedAsyncEnumerable<TElement> {
|
abstract class BaseOrderedAsyncEnumerable<TElement> extends BaseAsyncEnumerable<TElement> implements OrderedAsyncEnumerable<TElement> {
|
||||||
@@ -954,6 +1262,10 @@ abstract class BaseOrderedAsyncEnumerable<TElement> extends BaseAsyncEnumerable<
|
|||||||
return await this.#enumerable.nonEnumeratedCount();
|
return await this.#enumerable.nonEnumeratedCount();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override async maxCount() {
|
||||||
|
return await this.#enumerable.maxCount();
|
||||||
|
}
|
||||||
|
|
||||||
get comparer() {
|
get comparer() {
|
||||||
return this.#sorter;
|
return this.#sorter;
|
||||||
}
|
}
|
||||||
@@ -1922,7 +2234,7 @@ class GroupByAsyncEnumerable<TElement, TKey, TResult> extends BaseAsyncEnumerabl
|
|||||||
}
|
}
|
||||||
|
|
||||||
for await (const entry of groupings) {
|
for await (const entry of groupings) {
|
||||||
yield new GroupedAsyncEnumerableImpl(entry[0], array(entry[1]));
|
yield new GroupedAsyncEnumerableImpl(entry[0], AsyncEnumerable.array(entry[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2032,7 +2344,7 @@ class GroupJoinAsyncEnumerable<TOuter, TInner, TKey, TResult> extends BaseAsyncE
|
|||||||
}
|
}
|
||||||
|
|
||||||
// yield this.#resultSelector(firstObj, this.#second.where(secondObj => this.#keyComparer(firstKey, this.#secondKeySelector(secondObj))));
|
// yield this.#resultSelector(firstObj, this.#second.where(secondObj => this.#keyComparer(firstKey, this.#secondKeySelector(secondObj))));
|
||||||
yield this.#resultSelector(firstObj, array(secondObjs));
|
yield this.#resultSelector(firstObj, AsyncEnumerable.array(secondObjs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { join } from "./collector.js";
|
import { join } from "./collector.js";
|
||||||
import { arrayLike, sequence } from "./sync.js";
|
import { Enumerable } from "./sync.js";
|
||||||
import { asArray, isDefined } from "./utils.js";
|
import { asArray, isDefined } from "./utils.js";
|
||||||
|
|
||||||
export interface BitArray extends Iterable<boolean> {
|
export interface BitArray extends Iterable<boolean> {
|
||||||
@@ -224,16 +224,16 @@ class BitArrayImpl implements BitArray {
|
|||||||
this.#ensureSameSize(other);
|
this.#ensureSameSize(other);
|
||||||
|
|
||||||
return other instanceof BitArrayImpl ?
|
return other instanceof BitArrayImpl ?
|
||||||
arrayLike(this.#bits).zip(arrayLike(other.#bits)).all(([a, b]) => (a & b) === b) :
|
Enumerable.arrayLike(this.#bits).zip(Enumerable.arrayLike(other.#bits)).all(([a, b]) => (a & b) === b) :
|
||||||
sequence(this).zip(sequence(other)).where(([, b]) => b).all(([a, b]) => a && b);
|
Enumerable.sequence(this).zip(Enumerable.sequence(other)).where(([, b]) => b).all(([a, b]) => a && b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public intersects(other: BitArray) {
|
public intersects(other: BitArray) {
|
||||||
this.#ensureSameSize(other);
|
this.#ensureSameSize(other);
|
||||||
|
|
||||||
return other instanceof BitArrayImpl ?
|
return other instanceof BitArrayImpl ?
|
||||||
arrayLike(this.#bits).zip(arrayLike(other.#bits)).any(([a, b]) => (a & b) !== 0) :
|
Enumerable.arrayLike(this.#bits).zip(Enumerable.arrayLike(other.#bits)).any(([a, b]) => (a & b) !== 0) :
|
||||||
sequence(this).zip(sequence(other)).any(([a, b]) => a && b);
|
Enumerable.sequence(this).zip(Enumerable.sequence(other)).any(([a, b]) => a && b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public slice(offset: number, length: number) {
|
public slice(offset: number, length: number) {
|
||||||
@@ -247,15 +247,15 @@ class BitArrayImpl implements BitArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public toArray() {
|
public toArray() {
|
||||||
return sequence(this).toArray();
|
return Enumerable.sequence(this).toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public equals(other: BitArray) {
|
public equals(other: BitArray) {
|
||||||
return other === this || isDefined(other) && (other instanceof BitArrayImpl ? arrayLike(this.#bits).equals(arrayLike(other.#bits)) : sequence(this).equals(sequence(other)));
|
return other === this || isDefined(other) && (other instanceof BitArrayImpl ? Enumerable.arrayLike(this.#bits).sequenceEquals(Enumerable.arrayLike(other.#bits)) : Enumerable.sequence(this).sequenceEquals(Enumerable.sequence(other)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString() {
|
public toString() {
|
||||||
return sequence(this).select(bit => bit ? '1' : '0').collect(join());
|
return Enumerable.sequence(this).select(bit => bit ? '1' : '0').collect(join());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -465,13 +465,13 @@ class BitArraySlice implements BitArray {
|
|||||||
public contains(other: BitArray) {
|
public contains(other: BitArray) {
|
||||||
this.#ensureSameSize(other);
|
this.#ensureSameSize(other);
|
||||||
|
|
||||||
return sequence(this).zip(sequence(other)).where(([, b]) => b).all(([a, b]) => a && b);
|
return Enumerable.sequence(this).zip(Enumerable.sequence(other)).where(([, b]) => b).all(([a, b]) => a && b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public intersects(other: BitArray) {
|
public intersects(other: BitArray) {
|
||||||
this.#ensureSameSize(other);
|
this.#ensureSameSize(other);
|
||||||
|
|
||||||
return sequence(this).zip(sequence(other)).any(([a, b]) => a && b);
|
return Enumerable.sequence(this).zip(Enumerable.sequence(other)).any(([a, b]) => a && b);
|
||||||
}
|
}
|
||||||
|
|
||||||
public slice(offset: number, length: number) {
|
public slice(offset: number, length: number) {
|
||||||
@@ -489,15 +489,15 @@ class BitArraySlice implements BitArray {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public toArray() {
|
public toArray() {
|
||||||
return sequence(this).toArray();
|
return Enumerable.sequence(this).toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public equals(other: BitArray) {
|
public equals(other: BitArray) {
|
||||||
return other === this || isDefined(other) && sequence(this).equals(sequence(other));
|
return other === this || isDefined(other) && Enumerable.sequence(this).sequenceEquals(Enumerable.sequence(other));
|
||||||
}
|
}
|
||||||
|
|
||||||
public toString() {
|
public toString() {
|
||||||
return sequence(this).select(bit => bit ? '1' : '0').collect(join());
|
return Enumerable.sequence(this).select(bit => bit ? '1' : '0').collect(join());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export * from "./sync.js";
|
export * from "./sync.js";
|
||||||
export * as async from "./async.js";
|
export * from "./async.js";
|
||||||
export * as collectors from "./collector.js";
|
export * as collectors from "./collector.js";
|
||||||
export * as random from "./random.js";
|
export * as random from "./random.js";
|
||||||
|
|||||||
276
src/sync.ts
276
src/sync.ts
@@ -41,7 +41,7 @@ export interface Enumerable<TElement> extends Iterable<TElement> {
|
|||||||
|
|
||||||
contains(obj: TElement, equater?: Equater<TElement>): boolean;
|
contains(obj: TElement, equater?: Equater<TElement>): boolean;
|
||||||
|
|
||||||
equals(iterable: Iterable<TElement>, equater?: Equater<TElement>): boolean;
|
sequenceEquals(iterable: Iterable<TElement>, equater?: Equater<TElement>): boolean;
|
||||||
|
|
||||||
append(obj: TElement): Enumerable<TElement>;
|
append(obj: TElement): Enumerable<TElement>;
|
||||||
|
|
||||||
@@ -146,147 +146,149 @@ export interface OrderedEnumerable<TElement> extends Enumerable<TElement> {
|
|||||||
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedEnumerable<TElement>;
|
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedEnumerable<TElement>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wrap<T>(iterable: Iterable<T>): Enumerable<T> {
|
export namespace Enumerable {
|
||||||
if (isEnumerable<T>(iterable)) {
|
export function wrap<T>(iterable: Iterable<T>): Enumerable<T> {
|
||||||
return iterable;
|
if (isEnumerable<T>(iterable)) {
|
||||||
|
return iterable;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(iterable)) {
|
||||||
|
return array(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterable instanceof Set) {
|
||||||
|
return set<T>(iterable);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (iterable instanceof Map) {
|
||||||
|
return map(iterable) as unknown as Enumerable<T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
return sequence(iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(iterable)) {
|
export function sequence<T>(iterable: Iterable<T>): Enumerable<T> {
|
||||||
return array(iterable);
|
return new WrappedIterable(iterable);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iterable instanceof Set) {
|
export function empty<T>(): Enumerable<T> {
|
||||||
return set<T>(iterable);
|
return EmptyEnumerable.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (iterable instanceof Map) {
|
export function single<T>(obj: T): Enumerable<T> {
|
||||||
return map(iterable) as unknown as Enumerable<T>;
|
return new WrappedObject(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sequence(iterable);
|
export function array<T>(array: T[]): Enumerable<T> {
|
||||||
}
|
return new WrappedArray(array);
|
||||||
|
}
|
||||||
|
|
||||||
export function sequence<T>(iterable: Iterable<T>): Enumerable<T> {
|
export function arrayLike<T>(arrayLike: ArrayLike<T>): Enumerable<T> {
|
||||||
return new WrappedIterable(iterable);
|
return new WrappedArrayLike(arrayLike);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function empty<T>(): Enumerable<T> {
|
export function set<T>(set: Set<T>): Enumerable<T> {
|
||||||
return EmptyEnumerable.INSTANCE;
|
return new WrappedSet(set);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function single<T>(obj: T): Enumerable<T> {
|
export function map<K, V>(map: Map<K, V>): Enumerable<[K, V]> {
|
||||||
return new WrappedObject(obj);
|
return new WrappedMap(map);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function array<T>(array: T[]): Enumerable<T> {
|
export function of<T>(...elements: T[]): Enumerable<T> {
|
||||||
return new WrappedArray(array);
|
switch (elements.length) {
|
||||||
}
|
case 0:
|
||||||
|
return empty();
|
||||||
|
case 1:
|
||||||
|
return single(elements[0]);
|
||||||
|
default:
|
||||||
|
return array(elements);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function arrayLike<T>(arrayLike: ArrayLike<T>): Enumerable<T> {
|
export function ofPropertyKeys<T extends PropertyKey>(...elements: T[]): Enumerable<T> {
|
||||||
return new WrappedArrayLike(arrayLike);
|
return of(...elements);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function set<T>(set: Set<T>): Enumerable<T> {
|
export function entries<T>(o: Record<string, T> | ArrayLike<T>): Enumerable<[string, T]> {
|
||||||
return new WrappedSet(set);
|
return array(Object.entries(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function map<K, V>(map: Map<K, V>): Enumerable<[K, V]> {
|
export function keys(o: object): Enumerable<string> {
|
||||||
return new WrappedMap(map);
|
return array(Object.keys(o));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function of<T>(...elements: T[]): Enumerable<T> {
|
export function func<T>(f: () => T): Enumerable<T> {
|
||||||
switch (elements.length) {
|
return new FunctionEnumerable(f);
|
||||||
case 0:
|
}
|
||||||
|
|
||||||
|
export function generator<T>(generator: () => Iterable<T>): Enumerable<T> {
|
||||||
|
return new GeneratorEnumerable(generator);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function range(max: number): Enumerable<number>
|
||||||
|
export function range(min: number, max: number): Enumerable<number>
|
||||||
|
export function range(min: number, max: number, step: number): Enumerable<number>
|
||||||
|
export function range(a: number, b?: number, c?: number): Enumerable<number> {
|
||||||
|
if (b === undefined) {
|
||||||
|
b = a;
|
||||||
|
a = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c === undefined) {
|
||||||
|
c = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new RangeEnumerable(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function bigintRange(max: bigint): Enumerable<bigint>
|
||||||
|
export function bigintRange(min: bigint, max: bigint): Enumerable<bigint>
|
||||||
|
export function bigintRange(min: bigint, max: bigint, step: bigint): Enumerable<bigint>
|
||||||
|
export function bigintRange(a: bigint, b?: bigint, c?: bigint): Enumerable<bigint> {
|
||||||
|
if (b === undefined) {
|
||||||
|
b = a;
|
||||||
|
a = 0n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c === undefined) {
|
||||||
|
c = 1n;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new BigIntRangeEnumerable(a, b, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function repeat<T>(value: T, count?: number): Enumerable<T> {
|
||||||
|
if (count == undefined) {
|
||||||
|
return new RepeatForeverEnumerable(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count < 0) {
|
||||||
|
throw new RangeError();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (count === 0) {
|
||||||
return empty();
|
return empty();
|
||||||
case 1:
|
}
|
||||||
return single(elements[0]);
|
|
||||||
default:
|
|
||||||
return array(elements);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function ofPropertyKeys<T extends PropertyKey>(...elements: T[]): Enumerable<T> {
|
if (count === 1) {
|
||||||
return of(...elements);
|
return new WrappedObject(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function entries<T>(o: Record<string, T> | ArrayLike<T>): Enumerable<[string, T]> {
|
return new RepeatEnumerable(value, count);
|
||||||
return array(Object.entries(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function keys(o: object): Enumerable<string> {
|
|
||||||
return array(Object.keys(o));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function func<T>(f: () => T): Enumerable<T> {
|
|
||||||
return new FunctionEnumerable(f);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function generator<T>(generator: () => Iterable<T>): Enumerable<T> {
|
|
||||||
return new GeneratorEnumerable(generator);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function range(max: number): Enumerable<number>
|
|
||||||
export function range(min: number, max: number): Enumerable<number>
|
|
||||||
export function range(min: number, max: number, step: number): Enumerable<number>
|
|
||||||
export function range(a: number, b?: number, c?: number): Enumerable<number> {
|
|
||||||
if (b === undefined) {
|
|
||||||
b = a;
|
|
||||||
a = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c === undefined) {
|
export function randomSequence(random?: RandomGenerator): Enumerable<number> {
|
||||||
c = 1;
|
return new FunctionEnumerable(random ?? mathRandom);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new RangeEnumerable(a, b, c);
|
export function concat<T>(...enumerables: Enumerable<T>[]): Enumerable<T> {
|
||||||
}
|
return new ConcatEnumerable(enumerables);
|
||||||
|
|
||||||
export function bigintRange(max: bigint): Enumerable<bigint>
|
|
||||||
export function bigintRange(min: bigint, max: bigint): Enumerable<bigint>
|
|
||||||
export function bigintRange(min: bigint, max: bigint, step: bigint): Enumerable<bigint>
|
|
||||||
export function bigintRange(a: bigint, b?: bigint, c?: bigint): Enumerable<bigint> {
|
|
||||||
if (b === undefined) {
|
|
||||||
b = a;
|
|
||||||
a = 0n;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (c === undefined) {
|
export function isEnumerable<T = any>(obj: any): obj is Enumerable<T> {
|
||||||
c = 1n;
|
return obj instanceof EnumerableMarker;
|
||||||
}
|
}
|
||||||
|
|
||||||
return new BigIntRangeEnumerable(a, b, c);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function repeat<T>(value: T, count?: number): Enumerable<T> {
|
|
||||||
if (count == undefined) {
|
|
||||||
return new RepeatForeverEnumerable(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count < 0) {
|
|
||||||
throw new RangeError();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 0) {
|
|
||||||
return empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count === 1) {
|
|
||||||
return new WrappedObject(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return new RepeatEnumerable(value, count);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function randomSequence(random?: RandomGenerator): Enumerable<number> {
|
|
||||||
return new FunctionEnumerable(random ?? mathRandom);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function concat<T>(...enumerables: Enumerable<T>[]): Enumerable<T> {
|
|
||||||
return new ConcatEnumerable(enumerables);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isEnumerable<T = any>(obj: any): obj is Enumerable<T> {
|
|
||||||
return obj instanceof EnumerableMarker;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#region enumerable implementation
|
//#region enumerable implementation
|
||||||
@@ -323,11 +325,11 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
join<TOther, TKey, TResult>(iterable: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: Equater<TKey>): Enumerable<TResult> {
|
join<TOther, TKey, TResult>(iterable: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: Equater<TKey>): Enumerable<TResult> {
|
||||||
return new JoinEnumerable<TElement, TOther, TKey, TResult>(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
return new JoinEnumerable<TElement, TOther, TKey, TResult>(this, Enumerable.wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
groupJoin<TOther, TKey, TResult>(iterable: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Enumerable<TOther>, TResult>, keyComparer?: Equater<TKey>): Enumerable<TResult> {
|
groupJoin<TOther, TKey, TResult>(iterable: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Enumerable<TOther>, TResult>, keyComparer?: Equater<TKey>): Enumerable<TResult> {
|
||||||
return new GroupJoinEnumerable<TElement, TOther, TKey, TResult>(this, wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
return new GroupJoinEnumerable<TElement, TOther, TKey, TResult>(this, Enumerable.wrap(iterable), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||||
}
|
}
|
||||||
|
|
||||||
contains(obj: TElement, equater?: Equater<TElement>) {
|
contains(obj: TElement, equater?: Equater<TElement>) {
|
||||||
@@ -344,8 +346,12 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
equals(iterable: Iterable<TElement>, equater?: Equater<TElement>) {
|
sequenceEquals(iterable: Iterable<TElement>, equater?: Equater<TElement>) {
|
||||||
const that = wrap(iterable);
|
if (this === iterable) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const that = Enumerable.wrap(iterable);
|
||||||
|
|
||||||
const thisCount = this.nonEnumeratedCount();
|
const thisCount = this.nonEnumeratedCount();
|
||||||
const thatCount = that.nonEnumeratedCount();
|
const thatCount = that.nonEnumeratedCount();
|
||||||
@@ -399,7 +405,7 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
const arr: Enumerable<TElement>[] = [this];
|
const arr: Enumerable<TElement>[] = [this];
|
||||||
|
|
||||||
for (const iterable of iterables) {
|
for (const iterable of iterables) {
|
||||||
arr.push(wrap(iterable));
|
arr.push(Enumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ConcatEnumerable(arr);
|
return new ConcatEnumerable(arr);
|
||||||
@@ -743,27 +749,27 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
union(iterable: Iterable<TElement>, equater?: Equater<TElement>): Enumerable<TElement> {
|
union(iterable: Iterable<TElement>, equater?: Equater<TElement>): Enumerable<TElement> {
|
||||||
return new UnionEnumerable<TElement>(this, wrap(iterable), equater);
|
return new UnionEnumerable<TElement>(this, Enumerable.wrap(iterable), equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
unionBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Enumerable<TElement> {
|
unionBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Enumerable<TElement> {
|
||||||
return new UnionByEnumerable<TElement, TBy>(this, wrap(iterable), selector, equater);
|
return new UnionByEnumerable<TElement, TBy>(this, Enumerable.wrap(iterable), selector, equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
except(iterable: Iterable<TElement>): Enumerable<TElement> {
|
except(iterable: Iterable<TElement>): Enumerable<TElement> {
|
||||||
return new ExceptEnumerable<TElement>(this, wrap(iterable));
|
return new ExceptEnumerable<TElement>(this, Enumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
exceptBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>): Enumerable<TElement> {
|
exceptBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>): Enumerable<TElement> {
|
||||||
return new ExceptByEnumerable<TElement, TBy>(this, wrap(iterable), selector);
|
return new ExceptByEnumerable<TElement, TBy>(this, Enumerable.wrap(iterable), selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
intersect(iterable: Iterable<TElement>): Enumerable<TElement> {
|
intersect(iterable: Iterable<TElement>): Enumerable<TElement> {
|
||||||
return new IntersectEnumerable<TElement>(this, wrap(iterable));
|
return new IntersectEnumerable<TElement>(this, Enumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
intersectBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>): Enumerable<TElement> {
|
intersectBy<TBy>(iterable: Iterable<TElement>, selector: Converter<TElement, TBy>): Enumerable<TElement> {
|
||||||
return new IntersectByEnumerable<TElement, TBy>(this, wrap(iterable), selector);
|
return new IntersectByEnumerable<TElement, TBy>(this, Enumerable.wrap(iterable), selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
all(predicate: Predicate<TElement>) {
|
all(predicate: Predicate<TElement>) {
|
||||||
@@ -847,7 +853,7 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
throw new Error("Cannot take a negative number of elements.");
|
throw new Error("Cannot take a negative number of elements.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return n === 0 ? empty<TElement>() : new TakeEnumerable<TElement>(this, n);
|
return n === 0 ? Enumerable.empty<TElement>() : new TakeEnumerable<TElement>(this, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
takeLast(n: number): Enumerable<TElement> {
|
takeLast(n: number): Enumerable<TElement> {
|
||||||
@@ -855,7 +861,7 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
throw new Error("Cannot take a negative number of elements.");
|
throw new Error("Cannot take a negative number of elements.");
|
||||||
}
|
}
|
||||||
|
|
||||||
return n === 0 ? empty<TElement>() : new TakeLastEnumerable<TElement>(this, n);
|
return n === 0 ? Enumerable.empty<TElement>() : new TakeLastEnumerable<TElement>(this, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
takeWhile(predicate: Predicate<TElement>): Enumerable<TElement> {
|
takeWhile(predicate: Predicate<TElement>): Enumerable<TElement> {
|
||||||
@@ -873,7 +879,7 @@ export abstract class BaseEnumerable<TElement> extends EnumerableMarker implemen
|
|||||||
}
|
}
|
||||||
|
|
||||||
zip<TOther>(iterable: Iterable<TOther>): Enumerable<[TElement, TOther]> {
|
zip<TOther>(iterable: Iterable<TOther>): Enumerable<[TElement, TOther]> {
|
||||||
return new ZippedEnumerable<TElement, TOther>(this, wrap(iterable));
|
return new ZippedEnumerable<TElement, TOther>(this, Enumerable.wrap(iterable));
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed(): Enumerable<[number, TElement]> {
|
indexed(): Enumerable<[number, TElement]> {
|
||||||
@@ -1025,8 +1031,8 @@ class DelegatedEnumerable<TElement> extends EnumerableMarker implements Enumerab
|
|||||||
return this.#enumerable.contains(obj, equater);
|
return this.#enumerable.contains(obj, equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
equals(iterable: Iterable<TElement>, equater?: Equater<TElement>) {
|
sequenceEquals(iterable: Iterable<TElement>, equater?: Equater<TElement>) {
|
||||||
return this.#enumerable.equals(iterable, equater);
|
return this.#enumerable.sequenceEquals(iterable, equater);
|
||||||
}
|
}
|
||||||
|
|
||||||
append(obj: TElement) {
|
append(obj: TElement) {
|
||||||
@@ -2495,7 +2501,7 @@ class GroupByEnumerable<TElement, TKey, TResult> extends BaseEnumerable<GroupedE
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (const entry of groupings) {
|
for (const entry of groupings) {
|
||||||
yield new GroupedEnumerableImpl(entry[0], array(entry[1]));
|
yield new GroupedEnumerableImpl(entry[0], Enumerable.array(entry[1]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2624,7 +2630,7 @@ class GroupJoinEnumerable<TOuter, TInner, TKey, TResult> extends BaseEnumerable<
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield this.#resultSelector(firstObj, array(secondObjs));
|
yield this.#resultSelector(firstObj, Enumerable.array(secondObjs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2677,7 +2683,7 @@ class CacheEnumerable<T> extends DelegatedEnumerable<T> {
|
|||||||
|
|
||||||
override iterator() {
|
override iterator() {
|
||||||
if (!this.#cached) {
|
if (!this.#cached) {
|
||||||
this.enumerable = array(this.enumerable.toArray());
|
this.enumerable = Enumerable.array(this.enumerable.toArray());
|
||||||
this.#cached = true;
|
this.#cached = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user