sync
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
import { Collector } from "../collector/types.js";
|
||||
import { asAsyncComparer, combineNullableAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js";
|
||||
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js";
|
||||
import { strictEquals, identity } from "../equality-comparer/index.js";
|
||||
import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
|
||||
import { createAsyncEqualityMap } from "../equality-map.js";
|
||||
import { createAsyncEqualitySet } from "../equality-set.js";
|
||||
import { createQueue } from "../queue.js";
|
||||
@@ -6,8 +10,8 @@ import { getRandomElementAsync } from "../random/index.js";
|
||||
import { AsyncRandomOptions } from "../random/types.js";
|
||||
import { selectionSorter } from "../sorting.js";
|
||||
import { Sequence } from "../sync/types.js";
|
||||
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybeAsyncSequence, MaybePromise } from "../types.js";
|
||||
import { strictEquals, identity, operatorCompare, defaultArrayComparer, combineAsyncComparers, asAsyncIterable } from "../utils.js";
|
||||
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybePromise, MaybeAsyncIterable, MaybeAsyncTypePredicate } from "../types.js";
|
||||
import { asAsyncIterable } from "../utils.js";
|
||||
import { array, empty, wrap } from "./index.js";
|
||||
import { AsyncSequence, AsyncSequencePipeline, GroupedAsyncSequence, OrderedAsyncSequence } from "./types.js";
|
||||
|
||||
@@ -28,33 +32,35 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return new SelectAsyncSequence<TElement, TResult>(this, converter);
|
||||
}
|
||||
|
||||
selectMany<TResult>(converter: MaybeAsyncConverter<TElement, MaybeAsyncSequence<TResult>>): AsyncSequence<TResult> {
|
||||
selectMany<TResult>(converter: MaybeAsyncConverter<TElement, MaybeAsyncIterable<TResult>>): AsyncSequence<TResult> {
|
||||
return new SelectManyAsyncSequence<TElement, TResult>(this, converter);
|
||||
}
|
||||
|
||||
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement> {
|
||||
return new WhereAsyncSequence<TElement>(this, predicate);
|
||||
where<TFiltered extends TElement>(predicate: MaybeAsyncTypePredicate<TElement, TFiltered>): AsyncSequence<TFiltered>;
|
||||
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement>;
|
||||
where(predicate: any) {
|
||||
return new WhereAsyncSequence<TElement, any>(this, predicate);
|
||||
}
|
||||
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
|
||||
return new GroupByAsyncSequence<any, any, any>(this, keySelector, elementSelector, keyComparer);
|
||||
}
|
||||
|
||||
join<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<TResult>;
|
||||
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
|
||||
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||
return new JoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, AsyncSequence<TOther>, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<TResult>;
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
|
||||
groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||
return new GroupJoinAsyncSequence<any, any, any, any>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
async contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>) {
|
||||
async contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement>) {
|
||||
if (!equater) {
|
||||
equater = strictEquals;
|
||||
}
|
||||
@@ -68,7 +74,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return false;
|
||||
}
|
||||
|
||||
async sequenceEquals(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>) {
|
||||
async sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>) {
|
||||
if (this === sequence) {
|
||||
return true;
|
||||
}
|
||||
@@ -115,11 +121,11 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return new PrependAsyncSequence<TElement>(this, obj);
|
||||
}
|
||||
|
||||
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement> {
|
||||
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
|
||||
return new RemoveAsyncSequence<TElement>(this, obj, all, equater);
|
||||
}
|
||||
|
||||
concat(...sequences: MaybeAsyncSequence<TElement>[]): AsyncSequence<TElement> {
|
||||
concat(...sequences: MaybeAsyncIterable<TElement>[]): AsyncSequence<TElement> {
|
||||
if (sequences.length === 0) {
|
||||
return this;
|
||||
}
|
||||
@@ -391,7 +397,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return acc as unknown as TResult;
|
||||
}
|
||||
|
||||
async #find<TResult>(sorter: MaybeAsyncAnyPredicate<number>, selector?: MaybeAsyncConverter<TElement, TResult>, comparer?: MaybeAsyncComparer<TResult>) {
|
||||
async #find<TResult>(sorter: MaybeAsyncAnyPredicate<number>, selector?: MaybeAsyncConverter<TElement, TResult>, comparer?: MaybeAsyncComparisonOrComparer<TResult>) {
|
||||
const iterator = this.iterator();
|
||||
|
||||
let next = await iterator.next();
|
||||
@@ -404,9 +410,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
selector = identity as MaybeAsyncConverter<TElement, TResult>;
|
||||
}
|
||||
|
||||
if (!comparer) {
|
||||
comparer = operatorCompare;
|
||||
}
|
||||
comparer = comparer ? asAsyncComparer(comparer) : defaultAsyncComparer;
|
||||
|
||||
let result = next.value;
|
||||
let convertedResult = await selector(result);
|
||||
@@ -421,7 +425,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
const value = next.value;
|
||||
const convertedValue = await selector(value);
|
||||
|
||||
if (await sorter(await comparer(convertedResult, convertedValue))) {
|
||||
if (await sorter(await comparer.compare(convertedResult, convertedValue))) {
|
||||
result = value;
|
||||
convertedResult = convertedValue;
|
||||
}
|
||||
@@ -430,75 +434,125 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
return result;
|
||||
}
|
||||
|
||||
min(comparer?: MaybeAsyncComparer<TElement>) {
|
||||
min(comparer?: MaybeAsyncComparisonOrComparer<TElement>) {
|
||||
return this.#find(x => x > 0, undefined, comparer);
|
||||
}
|
||||
|
||||
minBy<TBy>(converter: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>) {
|
||||
minBy<TBy>(converter: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>) {
|
||||
return this.#find(x => x > 0, converter, comparer);
|
||||
}
|
||||
|
||||
max(comparer?: MaybeAsyncComparer<TElement>) {
|
||||
max(comparer?: MaybeAsyncComparisonOrComparer<TElement>) {
|
||||
return this.#find(x => x < 0, undefined, comparer);
|
||||
}
|
||||
|
||||
maxBy<TBy>(converter: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>) {
|
||||
maxBy<TBy>(converter: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>) {
|
||||
return this.#find(x => x < 0, converter, comparer);
|
||||
}
|
||||
|
||||
order(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
async #findBounds<TResult>(selector?: MaybeAsyncConverter<TElement, TResult>, comparer?: MaybeAsyncComparisonOrComparer<TResult>): Promise<[min: TElement, max: TElement]> {
|
||||
const iterator = this.iterator();
|
||||
|
||||
let next = await iterator.next();
|
||||
|
||||
if (next.done) {
|
||||
throw new Error("Sequence contains no element.");
|
||||
}
|
||||
|
||||
if (!selector) {
|
||||
selector = identity as MaybeAsyncConverter<TElement, TResult>;
|
||||
}
|
||||
|
||||
comparer = comparer ? asAsyncComparer(comparer) : defaultAsyncComparer;
|
||||
|
||||
let minBound = next.value, maxBound = minBound;
|
||||
let convertedMinBound = await selector(minBound), convertedMaxBound = convertedMinBound;
|
||||
|
||||
while (true) {
|
||||
next = await iterator.next();
|
||||
|
||||
if (next.done) {
|
||||
break;
|
||||
}
|
||||
|
||||
const value = next.value;
|
||||
const convertedValue = await selector(value);
|
||||
|
||||
if (await comparer.compare(convertedMinBound, convertedValue) > 0) {
|
||||
minBound = value;
|
||||
convertedMinBound = convertedValue;
|
||||
}
|
||||
|
||||
if (await comparer.compare(convertedMaxBound, convertedValue) < 0) {
|
||||
maxBound = value;
|
||||
convertedMaxBound = convertedValue;
|
||||
}
|
||||
}
|
||||
|
||||
return [minBound, maxBound];
|
||||
}
|
||||
|
||||
bounds(comparer?: MaybeAsyncComparisonOrComparer<TElement>) {
|
||||
return this.#findBounds(undefined, comparer);
|
||||
}
|
||||
|
||||
boundsBy<TBy>(converter: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>) {
|
||||
return this.#findBounds(converter, comparer);
|
||||
}
|
||||
|
||||
order(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
return new OrderAsyncSequence<TElement>(this, false, comparer);
|
||||
}
|
||||
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
return new OrderByAsyncSequence<TElement, TBy>(this, false, selector, comparer);
|
||||
}
|
||||
|
||||
orderDescending(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
return new OrderAsyncSequence<TElement>(this, true, comparer);
|
||||
}
|
||||
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
return new OrderByAsyncSequence<TElement, TBy>(this, true, selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<AsyncSequence<TElement>> {
|
||||
partition(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<AsyncSequence<TElement>> {
|
||||
return new PartitionAsyncSequence<TElement>(this, equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<AsyncSequence<TElement>> {
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<AsyncSequence<TElement>> {
|
||||
return new PartitionByAsyncSequence<TElement, TBy>(this, selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement> {
|
||||
distinct(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
|
||||
return new DistinctAsyncSequence<TElement>(this, equater);
|
||||
}
|
||||
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement> {
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement> {
|
||||
return new DistinctByAsyncSequence<TElement, TBy>(this, selector, equater);
|
||||
}
|
||||
|
||||
union(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement> {
|
||||
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement> {
|
||||
return new UnionAsyncSequence<TElement>(this, wrap(sequence), equater);
|
||||
}
|
||||
|
||||
unionBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement> {
|
||||
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement> {
|
||||
return new UnionByAsyncSequence<TElement, TBy>(this, wrap(sequence), selector, equater);
|
||||
}
|
||||
|
||||
except(sequence: MaybeAsyncSequence<TElement>): AsyncSequence<TElement> {
|
||||
except(sequence: MaybeAsyncIterable<TElement>): AsyncSequence<TElement> {
|
||||
return new ExceptAsyncSequence<TElement>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
exceptBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncSequence<TElement> {
|
||||
exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncSequence<TElement> {
|
||||
return new ExceptByAsyncSequence<TElement, TBy>(this, wrap(sequence), selector);
|
||||
}
|
||||
|
||||
intersect(sequence: MaybeAsyncSequence<TElement>): AsyncSequence<TElement> {
|
||||
intersect(sequence: MaybeAsyncIterable<TElement>): AsyncSequence<TElement> {
|
||||
return new IntersectAsyncSequence<TElement>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
intersectBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncSequence<TElement> {
|
||||
intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>): AsyncSequence<TElement> {
|
||||
return new IntersectByAsyncSequence<TElement, TBy>(this, wrap(sequence), selector);
|
||||
}
|
||||
|
||||
@@ -608,7 +662,7 @@ export abstract class BaseAsyncSequence<TElement> extends AsyncSequenceMarker im
|
||||
}
|
||||
}
|
||||
|
||||
zip<TOther>(sequence: MaybeAsyncSequence<TOther>): AsyncSequence<[TElement, TOther]> {
|
||||
zip<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]> {
|
||||
return new ZippedAsyncSequence<TElement, TOther>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
@@ -753,37 +807,39 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
|
||||
return this.#sequence.select(selector);
|
||||
}
|
||||
|
||||
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncSequence<TResult>>): AsyncSequence<TResult> {
|
||||
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncIterable<TResult>>): AsyncSequence<TResult> {
|
||||
return this.#sequence.selectMany(selector);
|
||||
}
|
||||
|
||||
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement> {
|
||||
where<TFiltered extends TElement>(predicate: MaybeAsyncTypePredicate<TElement, TFiltered>): AsyncSequence<TFiltered>;
|
||||
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement>;
|
||||
where(predicate: any) {
|
||||
return this.#sequence.where(predicate);
|
||||
}
|
||||
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
|
||||
return this.#sequence.groupBy(keySelector, elementSelector, keyComparer);
|
||||
}
|
||||
|
||||
join<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<TResult>;
|
||||
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
|
||||
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||
return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, AsyncSequence<TOther>, TResult>, keyComparer?: MaybeAsyncEquater<TKey> | undefined): AsyncSequence<TResult>;
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey> | undefined): AsyncSequence<TResult>;
|
||||
groupJoin(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||
return this.#sequence.groupJoin(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
contains(obj: TElement, equater?: MaybeAsyncEquater<TElement> | undefined): Promise<boolean> {
|
||||
contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): Promise<boolean> {
|
||||
return this.#sequence.contains(obj, equater);
|
||||
}
|
||||
|
||||
sequenceEquals(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement> | undefined): Promise<boolean> {
|
||||
sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): Promise<boolean> {
|
||||
return this.#sequence.sequenceEquals(sequence, equater);
|
||||
}
|
||||
|
||||
@@ -795,11 +851,11 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
|
||||
return this.#sequence.prepend(obj);
|
||||
}
|
||||
|
||||
remove(obj: TElement, all?: boolean | undefined, equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<TElement> {
|
||||
remove(obj: TElement, all?: boolean | undefined, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.remove(obj, all, equater);
|
||||
}
|
||||
|
||||
concat(...sequences: MaybeAsyncSequence<TElement>[]): AsyncSequence<TElement> {
|
||||
concat(...sequences: MaybeAsyncIterable<TElement>[]): AsyncSequence<TElement> {
|
||||
return this.#sequence.concat(...sequences);
|
||||
}
|
||||
|
||||
@@ -858,59 +914,67 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
|
||||
return this.#sequence.maxBy(selector);
|
||||
}
|
||||
|
||||
order(comparer?: MaybeAsyncComparer<TElement> | undefined): AsyncSequence<TElement> {
|
||||
bounds(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): Promise<[min: TElement, max: TElement]> {
|
||||
return this.#sequence.bounds(comparer);
|
||||
}
|
||||
|
||||
boundsBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): Promise<[min: TElement, max: TElement]> {
|
||||
return this.#sequence.boundsBy(selector, comparer);
|
||||
}
|
||||
|
||||
order(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.order(comparer);
|
||||
}
|
||||
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy> | undefined): AsyncSequence<TElement> {
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.orderBy(selector, comparer);
|
||||
}
|
||||
|
||||
orderDescending(comparer?: MaybeAsyncComparer<TElement> | undefined): AsyncSequence<TElement> {
|
||||
orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.orderDescending(comparer);
|
||||
}
|
||||
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy> | undefined): AsyncSequence<TElement> {
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.orderByDescending(selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<AsyncSequence<TElement>> {
|
||||
partition(equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<AsyncSequence<TElement>> {
|
||||
return this.#sequence.partition(equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<AsyncSequence<TElement>> {
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<AsyncSequence<TElement>> {
|
||||
return this.#sequence.partitionBy(selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<TElement> {
|
||||
distinct(equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.distinct(equater);
|
||||
}
|
||||
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<TElement> {
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.distinctBy(selector, equater);
|
||||
}
|
||||
|
||||
union(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<TElement> {
|
||||
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.union(wrap(sequence), equater);
|
||||
}
|
||||
|
||||
unionBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<TElement> {
|
||||
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.unionBy(wrap(sequence), selector, equater);
|
||||
}
|
||||
|
||||
except(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<TElement> {
|
||||
except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.except(wrap(sequence), equater);
|
||||
}
|
||||
|
||||
exceptBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<TElement> {
|
||||
exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.exceptBy(wrap(sequence), selector, equater);
|
||||
}
|
||||
|
||||
intersect(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement> | undefined): AsyncSequence<TElement> {
|
||||
intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.intersect(wrap(sequence), equater);
|
||||
}
|
||||
|
||||
intersectBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy> | undefined): AsyncSequence<TElement> {
|
||||
intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy> | undefined): AsyncSequence<TElement> {
|
||||
return this.#sequence.intersectBy(wrap(sequence), selector, equater);
|
||||
}
|
||||
|
||||
@@ -962,7 +1026,7 @@ export class DelegatedAsyncSequence<TElement> extends AsyncSequenceMarker implem
|
||||
return this.#sequence.forEach(action);
|
||||
}
|
||||
|
||||
zip<TOther>(sequence: MaybeAsyncSequence<TOther>): AsyncSequence<[TElement, TOther]> {
|
||||
zip<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]> {
|
||||
return this.#sequence.zip(wrap(sequence));
|
||||
}
|
||||
|
||||
@@ -1033,14 +1097,14 @@ export class GroupedAsyncSequenceImpl<TElement, TKey> extends DelegatedAsyncSequ
|
||||
|
||||
abstract class BaseOrderedAsyncSequence<TElement> extends BaseAsyncSequence<TElement> implements OrderedAsyncSequence<TElement> {
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #sorter: MaybeAsyncComparer<TElement>;
|
||||
readonly #sorter: AsyncComparer<TElement>;
|
||||
readonly #descending: boolean;
|
||||
|
||||
constructor(sequence: AsyncSequence<TElement>, sorter: MaybeAsyncComparer<TElement>, descending: boolean) {
|
||||
constructor(sequence: AsyncSequence<TElement>, sorter: MaybeAsyncComparisonOrComparer<TElement> | undefined, descending: boolean) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
this.#sorter = sorter;
|
||||
this.#sorter = sorter ? asAsyncComparer(sorter) : defaultAsyncComparer;
|
||||
this.#descending = descending;
|
||||
}
|
||||
|
||||
@@ -1056,19 +1120,19 @@ abstract class BaseOrderedAsyncSequence<TElement> extends BaseAsyncSequence<TEle
|
||||
return this.#sorter;
|
||||
}
|
||||
|
||||
thenSelf(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
thenSelf(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
return new ThenOrderAsyncSequence(this, false, comparer);
|
||||
}
|
||||
|
||||
thenBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
thenBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
return new ThenOrderByAsyncSequence<TElement, TBy>(this, false, selector, comparer);
|
||||
}
|
||||
|
||||
thenSelfDescending(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
thenSelfDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement> {
|
||||
return new ThenOrderAsyncSequence(this, true, comparer);
|
||||
}
|
||||
|
||||
thenByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
thenByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement> {
|
||||
return new ThenOrderByAsyncSequence<TElement, TBy>(this, true, selector, comparer);
|
||||
}
|
||||
|
||||
@@ -1079,7 +1143,7 @@ abstract class BaseOrderedAsyncSequence<TElement> extends BaseAsyncSequence<TEle
|
||||
arr.push(obj);
|
||||
}
|
||||
|
||||
await selectionSorter.sort(arr, this.#descending, this.#sorter);
|
||||
await selectionSorter.sort(arr, this.#descending, this.#sorter.comparison());
|
||||
|
||||
yield* arr;
|
||||
}
|
||||
@@ -1327,9 +1391,9 @@ export class ConcatAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
|
||||
class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, equater?: MaybeAsyncEquater<T>) {
|
||||
constructor(sequence: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1350,9 +1414,9 @@ class DistinctAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
readonly #equater: MaybeAsyncEquater<U> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEquater<U>) {
|
||||
constructor(sequence: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1373,11 +1437,11 @@ class DistinctByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
}
|
||||
|
||||
class WhereAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #predicate: MaybeAsyncAnyPredicate<T>;
|
||||
class WhereAsyncSequence<TElement, TFiltered extends TElement> extends BaseAsyncSequence<TFiltered> {
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #predicate: MaybeAsyncTypePredicate<TElement, TFiltered>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, predicate: MaybeAsyncAnyPredicate<T>) {
|
||||
constructor(sequence: AsyncSequence<TElement>, predicate: MaybeAsyncTypePredicate<TElement, TFiltered>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1387,7 +1451,7 @@ class WhereAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
override async *iterator() {
|
||||
for await (const obj of this.#sequence) {
|
||||
if (await this.#predicate(obj)) {
|
||||
yield obj;
|
||||
yield obj as TFiltered;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1395,9 +1459,9 @@ class WhereAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
|
||||
class SelectManyAsyncSequence<T, U> extends BaseAsyncSequence<U> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #converter: MaybeAsyncConverter<T, MaybeAsyncSequence<U>>;
|
||||
readonly #converter: MaybeAsyncConverter<T, MaybeAsyncIterable<U>>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, converter: MaybeAsyncConverter<T, MaybeAsyncSequence<U>>) {
|
||||
constructor(sequence: AsyncSequence<T>, converter: MaybeAsyncConverter<T, MaybeAsyncIterable<U>>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1640,37 +1704,26 @@ class TakeAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
}
|
||||
|
||||
class OrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparer<T>) {
|
||||
super(sequence, sorter ?? defaultArrayComparer, descending);
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparisonOrComparer<T>) {
|
||||
super(sequence, sorter, descending);
|
||||
}
|
||||
}
|
||||
|
||||
class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
super(sequence, OrderByAsyncSequence.#createSorter(selector, sorter), descending);
|
||||
}
|
||||
|
||||
static #createSorter<T, U>(selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
sorter ??= defaultArrayComparer;
|
||||
return async (a: T, b: T) => sorter(await selector(a), await selector(b));
|
||||
constructor(sequence: AsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparisonOrComparer<U>) {
|
||||
super(sequence, createAsyncComparerUsing(selector, sorter), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparer<T>) {
|
||||
super(sequence, combineAsyncComparers(sequence.comparer ?? defaultArrayComparer, sorter ?? defaultArrayComparer), descending);
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparisonOrComparer<T>) {
|
||||
super(sequence, combineNullableAsyncComparers([sequence.comparer, sorter]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
super(sequence, ThenOrderByAsyncSequence.#createCombinedSorter(sequence.comparer, selector, sorter), descending);
|
||||
}
|
||||
|
||||
static #createCombinedSorter<T, U>(baseSorter: MaybeAsyncComparer<T>, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparer<U>) {
|
||||
baseSorter ??= defaultArrayComparer;
|
||||
sorter ??= defaultArrayComparer;
|
||||
return combineAsyncComparers(baseSorter, async (a: T, b: T) => sorter(await selector(a), await selector(b)));
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparisonOrComparer<U>) {
|
||||
super(sequence, combineNullableAsyncComparers([sequence.comparer, createAsyncComparerUsing(selector, sorter)]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1783,9 +1836,9 @@ class ZippedAsyncSequence<T, U> extends BaseAsyncSequence<[T, U]> {
|
||||
class UnionAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEquater<T>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1816,9 +1869,9 @@ class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
readonly #equater: MaybeAsyncEquater<U> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEquater<U>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1849,9 +1902,9 @@ class UnionByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class ExceptAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEquater<T>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1880,9 +1933,9 @@ class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
readonly #equater: MaybeAsyncEquater<U> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEquater<U>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1911,9 +1964,9 @@ class ExceptByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
class IntersectAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEquater<T>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, equater?: MaybeAsyncEqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1942,9 +1995,9 @@ class IntersectByAsyncSequence<T, U> extends BaseAsyncSequence<T> {
|
||||
readonly #first: AsyncSequence<T>;
|
||||
readonly #second: AsyncSequence<T>;
|
||||
readonly #selector: MaybeAsyncConverter<T, U>;
|
||||
readonly #equater: MaybeAsyncEquater<U> | undefined;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEquater<U>) {
|
||||
constructor(first: AsyncSequence<T>, second: AsyncSequence<T>, selector: MaybeAsyncConverter<T, U>, equater?: MaybeAsyncEqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -1996,9 +2049,9 @@ class GroupByAsyncSequence<TElement, TKey, TResult> extends BaseAsyncSequence<Gr
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #keySelector: MaybeAsyncConverter<TElement, TKey>;
|
||||
readonly #elementSelector: MaybeAsyncConverter<TElement, TResult>;
|
||||
readonly #keyComparer: MaybeAsyncEquater<TKey> | undefined;
|
||||
readonly #keyComparer: MaybeAsyncEqualityComparison<TKey> | undefined;
|
||||
|
||||
constructor(sequence: AsyncSequence<TElement>, keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEquater<TKey>) {
|
||||
constructor(sequence: AsyncSequence<TElement>, keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2069,9 +2122,9 @@ class JoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSequence
|
||||
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
|
||||
readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>;
|
||||
readonly #resultSelector: MaybeAsyncBiConverter<TOuter, TInner, TResult>;
|
||||
readonly #keyComparer: MaybeAsyncEquater<TKey>;
|
||||
readonly #keyComparer: MaybeAsyncEqualityComparison<TKey>;
|
||||
|
||||
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, TInner, TResult>, keyComparer?: MaybeAsyncEquater<TKey>) {
|
||||
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, TInner, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2102,17 +2155,17 @@ class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSeq
|
||||
readonly #second: AsyncSequence<TInner>;
|
||||
readonly #firstKeySelector: MaybeAsyncConverter<TOuter, TKey>;
|
||||
readonly #secondKeySelector: MaybeAsyncConverter<TInner, TKey>;
|
||||
readonly #resultSelector: MaybeAsyncBiConverter<TOuter, AsyncSequence<TInner>, TResult>;
|
||||
readonly #keyComparer: MaybeAsyncEquater<TKey>;
|
||||
readonly #resultSelector: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>;
|
||||
readonly #keyComparer: MaybeAsyncEqualityComparison<TKey>;
|
||||
|
||||
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, AsyncSequence<TInner>, TResult>, keyComparer?: MaybeAsyncEquater<TKey>) {
|
||||
constructor(first: AsyncSequence<TOuter>, second: AsyncSequence<TInner>, firstKeySelector: MaybeAsyncConverter<TOuter, TKey>, secondKeySelector: MaybeAsyncConverter<TInner, TKey>, resultSelector?: MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
this.#second = second;
|
||||
this.#firstKeySelector = firstKeySelector;
|
||||
this.#secondKeySelector = secondKeySelector;
|
||||
this.#resultSelector = resultSelector ?? GroupJoinAsyncSequence.#defaultResultSelector as MaybeAsyncBiConverter<TOuter, AsyncSequence<TInner>, TResult>;
|
||||
this.#resultSelector = resultSelector ?? GroupJoinAsyncSequence.#defaultResultSelector as MaybeAsyncBiConverter<TOuter, MaybeAsyncIterable<TInner>, TResult>;
|
||||
this.#keyComparer = keyComparer ?? strictEquals;
|
||||
}
|
||||
|
||||
@@ -2133,7 +2186,6 @@ class GroupJoinAsyncSequence<TOuter, TInner, TKey, TResult> extends BaseAsyncSeq
|
||||
}
|
||||
}
|
||||
|
||||
// yield this.#resultSelector(firstObj, this.#second.where(secondObj => this.#keyComparer(firstKey, this.#secondKeySelector(secondObj))));
|
||||
yield this.#resultSelector(firstObj, array(secondObjs));
|
||||
}
|
||||
}
|
||||
@@ -2143,9 +2195,9 @@ class RemoveAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #obj: T;
|
||||
readonly #all: boolean;
|
||||
readonly #equater: MaybeAsyncEquater<T>;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, obj: T, all?: boolean, equater?: MaybeAsyncEquater<T>) {
|
||||
constructor(sequence: AsyncSequence<T>, obj: T, all?: boolean, equater?: MaybeAsyncEqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2202,9 +2254,9 @@ class CacheAsyncSequence<T> extends BaseAsyncSequence<T> {
|
||||
|
||||
class PartitionAsyncSequence<T> extends BaseAsyncSequence<AsyncSequence<T>> {
|
||||
readonly #sequence: AsyncSequence<T>;
|
||||
readonly #equater: MaybeAsyncEquater<T>;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T>;
|
||||
|
||||
constructor(sequence: AsyncSequence<T>, equater: MaybeAsyncEquater<T> | undefined) {
|
||||
constructor(sequence: AsyncSequence<T>, equater: MaybeAsyncEqualityComparison<T> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2233,9 +2285,9 @@ class PartitionAsyncSequence<T> extends BaseAsyncSequence<AsyncSequence<T>> {
|
||||
class PartitionByAsyncSequence<TElement, TBy> extends BaseAsyncSequence<AsyncSequence<TElement>> {
|
||||
readonly #sequence: AsyncSequence<TElement>;
|
||||
readonly #selector: MaybeAsyncConverter<TElement, TBy>;
|
||||
readonly #equater: MaybeAsyncEquater<TBy>;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<TBy>;
|
||||
|
||||
constructor(sequence: AsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater: MaybeAsyncEquater<TBy> | undefined) {
|
||||
constructor(sequence: AsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater: MaybeAsyncEqualityComparison<TBy> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { Collector } from "../collector/types.js";
|
||||
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js";
|
||||
import { MaybeAsyncEqualityComparison } from "../equality-comparer/types.js";
|
||||
import { AsyncRandomOptions } from "../random/types.js";
|
||||
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybeAsyncSequence, MaybeAsyncFunction, MaybePromise } from "../types.js";
|
||||
import { MaybeAsyncAnyPredicate, MaybeAsyncConverter, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncAction, MaybeAsyncFunction, MaybePromise, MaybeAsyncIterable } from "../types.js";
|
||||
|
||||
export type AsyncSequencePipeline<TElement, TResult> = MaybeAsyncFunction<(sequence: AsyncSequence<TElement>) => TResult>;
|
||||
|
||||
@@ -15,30 +17,31 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
|
||||
maxCount(): Promise<number>;
|
||||
|
||||
select<TResult>(selector: MaybeAsyncConverter<TElement, TResult>): AsyncSequence<TResult>;
|
||||
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncSequence<TResult>>): AsyncSequence<TResult>;
|
||||
selectMany<TResult>(selector: MaybeAsyncConverter<TElement, MaybeAsyncIterable<TResult>>): AsyncSequence<TResult>;
|
||||
|
||||
where<TFiltered extends TElement>(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TFiltered>;
|
||||
where(predicate: MaybeAsyncAnyPredicate<TElement>): AsyncSequence<TElement>;
|
||||
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
groupBy<TKey>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: MaybeAsyncConverter<TElement, TKey>, elementSelector: MaybeAsyncConverter<TElement, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TKey, TResult>>;
|
||||
|
||||
join<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<TResult>;
|
||||
join<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, TOther, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<TResult>;
|
||||
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncSequence<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, AsyncSequence<TOther>, TResult>, keyComparer?: MaybeAsyncEquater<TKey>): AsyncSequence<TResult>;
|
||||
groupJoin<TOther, TKey>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector?: undefined, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<GroupedAsyncSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: MaybeAsyncIterable<TOther>, firstKeySelector: MaybeAsyncConverter<TElement, TKey>, secondKeySelector: MaybeAsyncConverter<TOther, TKey>, resultSelector: MaybeAsyncBiConverter<TElement, MaybeAsyncIterable<TOther>, TResult>, keyComparer?: MaybeAsyncEqualityComparison<TKey>): AsyncSequence<TResult>;
|
||||
|
||||
contains(obj: TElement, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
||||
contains(obj: TElement, equater?: MaybeAsyncEqualityComparison<TElement>): Promise<boolean>;
|
||||
|
||||
sequenceEquals(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>): Promise<boolean>;
|
||||
sequenceEquals(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): Promise<boolean>;
|
||||
|
||||
append(obj: TElement): AsyncSequence<TElement>;
|
||||
|
||||
prepend(obj: TElement): AsyncSequence<TElement>;
|
||||
|
||||
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
remove(obj: TElement, all?: boolean, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
|
||||
|
||||
concat(...sequences: MaybeAsyncSequence<TElement>[]): AsyncSequence<TElement>;
|
||||
concat(...sequences: MaybeAsyncIterable<TElement>[]): AsyncSequence<TElement>;
|
||||
|
||||
first(predicate?: MaybeAsyncAnyPredicate<TElement>): Promise<TElement>;
|
||||
firstOrDefault(predicate?: MaybeAsyncAnyPredicate<TElement>, def?: TElement): Promise<TElement | undefined>;
|
||||
@@ -62,26 +65,29 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
|
||||
max(): Promise<TElement>;
|
||||
maxBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>): Promise<TElement>;
|
||||
|
||||
order(comparer?: MaybeAsyncComparer<TElement>): AsyncSequence<TElement>;
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): AsyncSequence<TElement>;
|
||||
bounds(comparer?: MaybeAsyncComparisonOrComparer<TElement>): Promise<[min: TElement, max: TElement]>;
|
||||
boundsBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): Promise<[min: TElement, max: TElement]>;
|
||||
|
||||
orderDescending(comparer?: MaybeAsyncComparer<TElement>): AsyncSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): AsyncSequence<TElement>;
|
||||
order(comparer?: MaybeAsyncComparisonOrComparer<TElement>): AsyncSequence<TElement>;
|
||||
orderBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
partition(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<AsyncSequence<TElement>>;
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<AsyncSequence<TElement>>;
|
||||
orderDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): AsyncSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
distinct(equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement>;
|
||||
partition(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<AsyncSequence<TElement>>;
|
||||
partitionBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<AsyncSequence<TElement>>;
|
||||
|
||||
union(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
unionBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement>;
|
||||
distinct(equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
|
||||
distinctBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
except(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
exceptBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement>;
|
||||
union(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
|
||||
unionBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
intersect(sequence: MaybeAsyncSequence<TElement>, equater?: MaybeAsyncEquater<TElement>): AsyncSequence<TElement>;
|
||||
intersectBy<TBy>(sequence: MaybeAsyncSequence<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEquater<TBy>): AsyncSequence<TElement>;
|
||||
except(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
|
||||
exceptBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
intersect(sequence: MaybeAsyncIterable<TElement>, equater?: MaybeAsyncEqualityComparison<TElement>): AsyncSequence<TElement>;
|
||||
intersectBy<TBy>(sequence: MaybeAsyncIterable<TElement>, selector: MaybeAsyncConverter<TElement, TBy>, equater?: MaybeAsyncEqualityComparison<TBy>): AsyncSequence<TElement>;
|
||||
|
||||
all(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>;
|
||||
any(predicate: MaybeAsyncAnyPredicate<TElement>): Promise<boolean>;
|
||||
@@ -101,7 +107,7 @@ export interface AsyncSequence<TElement> extends AsyncIterable<TElement> {
|
||||
|
||||
forEach(action: MaybeAsyncAction<TElement>): Promise<void>;
|
||||
|
||||
zip<TOther>(sequence: MaybeAsyncSequence<TOther>): AsyncSequence<[TElement, TOther]>;
|
||||
zip<TOther>(sequence: MaybeAsyncIterable<TOther>): AsyncSequence<[TElement, TOther]>;
|
||||
|
||||
indexed(): AsyncSequence<[number, TElement]>;
|
||||
|
||||
@@ -131,13 +137,13 @@ export interface GroupedAsyncSequence<TKey, TElement> extends AsyncSequence<TEle
|
||||
}
|
||||
|
||||
export interface OrderedAsyncSequence<TElement> extends AsyncSequence<TElement> {
|
||||
get comparer(): MaybeAsyncComparer<TElement>;
|
||||
get comparer(): AsyncComparer<TElement>;
|
||||
|
||||
thenSelf(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement>;
|
||||
thenSelf(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement>;
|
||||
|
||||
thenBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement>;
|
||||
thenBy<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement>;
|
||||
|
||||
thenSelfDescending(comparer?: MaybeAsyncComparer<TElement>): OrderedAsyncSequence<TElement>;
|
||||
thenSelfDescending(comparer?: MaybeAsyncComparisonOrComparer<TElement>): OrderedAsyncSequence<TElement>;
|
||||
|
||||
thenByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparer<TBy>): OrderedAsyncSequence<TElement>;
|
||||
thenByDescending<TBy>(selector: MaybeAsyncConverter<TElement, TBy>, comparer?: MaybeAsyncComparisonOrComparer<TBy>): OrderedAsyncSequence<TElement>;
|
||||
}
|
||||
|
||||
@@ -65,6 +65,37 @@ export class ToObjectCollector<TElement, TKey extends PropertyKey, TValue> imple
|
||||
}
|
||||
}
|
||||
|
||||
export class ToObjectListCollector<TElement, TKey extends PropertyKey, TValue> implements Collector<TElement, Record<TKey, TValue[]>, Record<TKey, TValue[]>> {
|
||||
readonly #keySelector: Converter<TElement, TKey>;
|
||||
readonly #valueSelector: Converter<TElement, TValue>;
|
||||
|
||||
constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
|
||||
this.#keySelector = keySelector;
|
||||
this.#valueSelector = valueSelector;
|
||||
}
|
||||
|
||||
initialize() {
|
||||
return {} as Record<TKey, TValue[]>;
|
||||
}
|
||||
|
||||
accumulate(accumulator: Record<TKey, TValue[]>, element: TElement) {
|
||||
const key = this.#keySelector(element);
|
||||
const value = this.#valueSelector(element);
|
||||
|
||||
const l = accumulator[key];
|
||||
|
||||
if (l) {
|
||||
l.push(value);
|
||||
} else {
|
||||
accumulator[key] = [value];
|
||||
}
|
||||
}
|
||||
|
||||
finalize(accumulator: Record<TKey, TValue[]>) {
|
||||
return accumulator;
|
||||
}
|
||||
}
|
||||
|
||||
export class ToMapCollector<TElement, TKey, TValue> implements Collector<TElement, Map<TKey, TValue>, Map<TKey, TValue>> {
|
||||
readonly #keySelector: Converter<TElement, TKey>;
|
||||
readonly #valueSelector: Converter<TElement, TValue>;
|
||||
@@ -90,6 +121,37 @@ export class ToMapCollector<TElement, TKey, TValue> implements Collector<TElemen
|
||||
}
|
||||
}
|
||||
|
||||
export class ToMapListCollector<TElement, TKey, TValue> implements Collector<TElement, Map<TKey, TValue[]>, Map<TKey, TValue[]>> {
|
||||
readonly #keySelector: Converter<TElement, TKey>;
|
||||
readonly #valueSelector: Converter<TElement, TValue>;
|
||||
|
||||
constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
|
||||
this.#keySelector = keySelector;
|
||||
this.#valueSelector = valueSelector;
|
||||
}
|
||||
|
||||
initialize() {
|
||||
return new Map<TKey, TValue[]>();
|
||||
}
|
||||
|
||||
accumulate(accumulator: Map<TKey, TValue[]>, element: TElement) {
|
||||
const key = this.#keySelector(element);
|
||||
const value = this.#valueSelector(element);
|
||||
|
||||
const l = accumulator.get(key);
|
||||
|
||||
if (l) {
|
||||
l.push(value);
|
||||
} else {
|
||||
accumulator.set(key, [value]);
|
||||
}
|
||||
}
|
||||
|
||||
finalize(accumulator: Map<TKey, TValue[]>) {
|
||||
return accumulator;
|
||||
}
|
||||
}
|
||||
|
||||
export class ToSetCollector<TElement> implements Collector<TElement, Set<TElement>, Set<TElement>> {
|
||||
initialize() {
|
||||
return new Set<TElement>();
|
||||
@@ -128,60 +190,60 @@ export class JoinCollector implements Collector<any, any[], string> {
|
||||
}
|
||||
}
|
||||
|
||||
export class SumCollector implements Collector<number, { sum: number }, number> {
|
||||
export class SumCollector implements Collector<number, { sum: number; }, number> {
|
||||
initialize() {
|
||||
return { sum: 0 };
|
||||
}
|
||||
|
||||
accumulate(accumulator: { sum: number }, element: number) {
|
||||
accumulate(accumulator: { sum: number; }, element: number) {
|
||||
accumulator.sum += element;
|
||||
}
|
||||
|
||||
finalize(accumulator: { sum: number }) {
|
||||
finalize(accumulator: { sum: number; }) {
|
||||
return accumulator.sum;
|
||||
}
|
||||
}
|
||||
|
||||
export class BigIntSumCollector implements Collector<bigint, { sum: bigint }, bigint> {
|
||||
export class BigIntSumCollector implements Collector<bigint, { sum: bigint; }, bigint> {
|
||||
initialize() {
|
||||
return { sum: 0n, };
|
||||
}
|
||||
|
||||
accumulate(accumulator: { sum: bigint }, element: bigint) {
|
||||
accumulate(accumulator: { sum: bigint; }, element: bigint) {
|
||||
accumulator.sum += element;
|
||||
}
|
||||
|
||||
finalize(accumulator: { sum: bigint }) {
|
||||
finalize(accumulator: { sum: bigint; }) {
|
||||
return accumulator.sum;
|
||||
}
|
||||
}
|
||||
|
||||
export class AverageCollector implements Collector<number, { count: number, sum: number }, number> {
|
||||
export class AverageCollector implements Collector<number, { count: number, sum: number; }, number> {
|
||||
initialize() {
|
||||
return { count: 0, sum: 0 };
|
||||
}
|
||||
|
||||
accumulate(accumulator: { count: number, sum: number }, element: number) {
|
||||
accumulate(accumulator: { count: number, sum: number; }, element: number) {
|
||||
accumulator.count++;
|
||||
accumulator.sum += element;
|
||||
}
|
||||
|
||||
finalize(accumulator: { count: number, sum: number }) {
|
||||
finalize(accumulator: { count: number, sum: number; }) {
|
||||
return accumulator.count === 0 ? 0 : accumulator.sum / accumulator.count;
|
||||
}
|
||||
}
|
||||
|
||||
export class BigIntAverageCollector implements Collector<bigint, { count: number, sum: bigint }, bigint> {
|
||||
export class BigIntAverageCollector implements Collector<bigint, { count: number, sum: bigint; }, bigint> {
|
||||
initialize() {
|
||||
return { count: 0, sum: 0n };
|
||||
}
|
||||
|
||||
accumulate(accumulator: { count: number, sum: bigint }, element: bigint) {
|
||||
accumulate(accumulator: { count: number, sum: bigint; }, element: bigint) {
|
||||
accumulator.count++;
|
||||
accumulator.sum += element;
|
||||
}
|
||||
|
||||
finalize(accumulator: { count: number, sum: bigint }) {
|
||||
finalize(accumulator: { count: number, sum: bigint; }) {
|
||||
return accumulator.count === 0 ? 0n : accumulator.sum / BigInt(accumulator.count);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Converter } from "../types.js";
|
||||
import { SimpleCollector, ToArrayCollector, ToObjectCollector, ToMapCollector, ToSetCollector, JoinCollector, SumCollector, BigIntSumCollector, AverageCollector, BigIntAverageCollector } from "./impl.js";
|
||||
import { SimpleCollector, ToArrayCollector, ToObjectCollector, ToMapCollector, ToSetCollector, JoinCollector, SumCollector, BigIntSumCollector, AverageCollector, BigIntAverageCollector, ToObjectListCollector, ToMapListCollector } from "./impl.js";
|
||||
import { Collector } from "./types.js";
|
||||
|
||||
export function create<TElement, TAccumulator, TResult>(initialize: () => TAccumulator, accumulate: (accumulator: TAccumulator, element: TElement) => void,
|
||||
@@ -17,10 +17,18 @@ export function toObject<TElement, TKey extends PropertyKey, TValue>(keySelector
|
||||
return new ToObjectCollector<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
}
|
||||
|
||||
export function toObjectList<TElement, TKey extends PropertyKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Record<TKey, TValue[]>> {
|
||||
return new ToObjectListCollector<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
}
|
||||
|
||||
export function toMap<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Map<TKey, TValue>> {
|
||||
return new ToMapCollector<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
}
|
||||
|
||||
export function toMapList<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): Collector<TElement, any, Map<TKey, TValue[]>> {
|
||||
return new ToMapListCollector<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
}
|
||||
|
||||
const toSetCollector = new ToSetCollector<any>();
|
||||
|
||||
export function toSet<TElement>(): Collector<TElement, any, Set<TElement>> {
|
||||
|
||||
219
src/collector/v2/impl.ts
Normal file
219
src/collector/v2/impl.ts
Normal file
@@ -0,0 +1,219 @@
|
||||
// import { Converter } from "../../types.js";
|
||||
// import { CollectorFactory, CollectorInstance } from "./types.js";
|
||||
|
||||
// export class ToArrayCollectorFactory<TElement> implements CollectorFactory<TElement, TElement[]> {
|
||||
// initialize() {
|
||||
// return new ToArrayCollectorInstance<TElement>();
|
||||
// }
|
||||
// };
|
||||
|
||||
// class ToArrayCollectorInstance<TElement> implements CollectorInstance<TElement, TElement[]> {
|
||||
// readonly #accumulator: TElement[];
|
||||
|
||||
// constructor() {
|
||||
// this.#accumulator = [];
|
||||
// }
|
||||
|
||||
// accumulate(element: TElement) {
|
||||
// this.#accumulator.push(element);
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class ToObjectCollectorFactory<TElement, TKey extends PropertyKey, TValue> implements CollectorFactory<TElement, Record<TKey, TValue>> {
|
||||
// readonly #keySelector: Converter<TElement, TKey>;
|
||||
// readonly #valueSelector: Converter<TElement, TValue>;
|
||||
|
||||
// constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
|
||||
// this.#keySelector = keySelector;
|
||||
// this.#valueSelector = valueSelector;
|
||||
// }
|
||||
|
||||
// get keySelector() {
|
||||
// return this.#keySelector;
|
||||
// }
|
||||
|
||||
// get valueSelector() {
|
||||
// return this.#valueSelector;
|
||||
// }
|
||||
|
||||
// initialize() {
|
||||
// return new ToObjectCollectorInstance<TElement, TKey, TValue>(this);
|
||||
// }
|
||||
// }
|
||||
|
||||
// class ToObjectCollectorInstance<TElement, TKey extends PropertyKey, TValue> implements CollectorInstance<TElement, Record<TKey, TValue>> {
|
||||
// readonly #factory: ToObjectCollectorFactory<TElement, TKey, TValue>;
|
||||
// readonly #accumulator = <Record<TKey, TValue>>{};
|
||||
|
||||
// constructor(factory: ToObjectCollectorFactory<TElement, TKey, TValue>) {
|
||||
// this.#factory = factory;
|
||||
// }
|
||||
|
||||
// accumulate(element: TElement) {
|
||||
// const key = this.#factory.keySelector(element);
|
||||
// const value = this.#factory.valueSelector(element);
|
||||
|
||||
// this.#accumulator[key] = value;
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class ToMapCollectorFactory<TElement, TKey extends PropertyKey, TValue> implements CollectorFactory<TElement, Map<TKey, TValue>> {
|
||||
// readonly #keySelector: Converter<TElement, TKey>;
|
||||
// readonly #valueSelector: Converter<TElement, TValue>;
|
||||
|
||||
// constructor(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>) {
|
||||
// this.#keySelector = keySelector;
|
||||
// this.#valueSelector = valueSelector;
|
||||
// }
|
||||
|
||||
// get keySelector() {
|
||||
// return this.#keySelector;
|
||||
// }
|
||||
|
||||
// get valueSelector() {
|
||||
// return this.#valueSelector;
|
||||
// }
|
||||
|
||||
// initialize() {
|
||||
// return new ToMapCollectorInstance<TElement, TKey, TValue>(this);
|
||||
// }
|
||||
// }
|
||||
|
||||
// class ToMapCollectorInstance<TElement, TKey extends PropertyKey, TValue> implements CollectorInstance<TElement, Map<TKey, TValue>> {
|
||||
// readonly #factory: ToMapCollectorFactory<TElement, TKey, TValue>;
|
||||
// readonly #accumulator = new Map<TKey, TValue>();
|
||||
|
||||
// constructor(factory: ToMapCollectorFactory<TElement, TKey, TValue>) {
|
||||
// this.#factory = factory;
|
||||
// }
|
||||
|
||||
// accumulate(element: TElement) {
|
||||
// const key = this.#factory.keySelector(element);
|
||||
// const value = this.#factory.valueSelector(element);
|
||||
|
||||
// this.#accumulator.set(key, value);
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class ToSetCollectorFactory<TElement> implements CollectorFactory<TElement, Set<TElement>> {
|
||||
// initialize() {
|
||||
// return new ToSetCollectorInstance<TElement>();
|
||||
// }
|
||||
// }
|
||||
|
||||
// class ToSetCollectorInstance<TElement> implements CollectorInstance<TElement, Set<TElement>> {
|
||||
// readonly #accumulator = new Set<TElement>();
|
||||
|
||||
// accumulate(element: TElement) {
|
||||
// this.#accumulator.add(element);
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class JoinCollectorFactory implements CollectorFactory<any, string> {
|
||||
// readonly #delimiter: string;
|
||||
// readonly #prefix: string;
|
||||
// readonly #suffix: string;
|
||||
|
||||
// constructor(delimiter?: string, prefix?: string, suffix?: string) {
|
||||
// this.#delimiter = delimiter ?? "";
|
||||
// this.#prefix = prefix ?? "";
|
||||
// this.#suffix = suffix ?? "";
|
||||
// }
|
||||
|
||||
// accumulate(element: string) {
|
||||
// this.#accumulator.push(element);
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#prefix + this.#accumulator.join(this.#delimiter) + this.#suffix;
|
||||
// }
|
||||
// }
|
||||
|
||||
// class JoinCollectorInstance implements CollectorInstance<any, string> {
|
||||
// readonly #delimiter: string;
|
||||
// readonly #prefix: string;
|
||||
// readonly #suffix: string;
|
||||
// readonly #accumulator: any[] = [];
|
||||
|
||||
// constructor(delimiter: string, prefix: string, suffix: string) {
|
||||
// this.#delimiter = delimiter ?? "";
|
||||
// this.#prefix = prefix ?? "";
|
||||
// this.#suffix = suffix ?? "";
|
||||
// }
|
||||
|
||||
// accumulate(element: string) {
|
||||
// this.#accumulator.push(element);
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#prefix + this.#accumulator.join(this.#delimiter) + this.#suffix;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class SumCollectorInstance implements CollectorInstance<number, number> {
|
||||
// #accumulator = 0;
|
||||
|
||||
// accumulate(element: number) {
|
||||
// this.#accumulator += element;
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class BigIntSumCollectorInstance implements CollectorInstance<bigint, bigint> {
|
||||
// #accumulator = 0n;
|
||||
|
||||
// accumulate(element: bigint) {
|
||||
// this.#accumulator += element;
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#accumulator;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class AverageCollectorInstance implements CollectorInstance<number, number> {
|
||||
// #count = 0;
|
||||
// #sum = 0;
|
||||
|
||||
// accumulate(element: number) {
|
||||
// this.#count++;
|
||||
// this.#sum += element;
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#count === 0 ? 0 : this.#sum / this.#count;
|
||||
// }
|
||||
// }
|
||||
|
||||
// export class BigIntAverageCollectorInstance implements CollectorInstance<bigint, bigint> {
|
||||
// #count = 0n;
|
||||
// #sum = 0n;
|
||||
|
||||
// accumulate(element: bigint) {
|
||||
// this.#count++;
|
||||
// this.#sum += element;
|
||||
// }
|
||||
|
||||
// finalize() {
|
||||
// return this.#count === 0n ? 0n : this.#sum / this.#count;
|
||||
// }
|
||||
// }
|
||||
57
src/collector/v2/index.ts
Normal file
57
src/collector/v2/index.ts
Normal file
@@ -0,0 +1,57 @@
|
||||
// import { Converter } from "../../types.js";
|
||||
// import { ToArrayCollectorInstance, ToObjectCollectorInstance, ToMapCollectorInstance, ToSetCollectorInstance, JoinCollectorInstance, SumCollectorInstance, BigIntSumCollectorInstance, AverageCollectorInstance, BigIntAverageCollectorInstance, ToArrayCollectorFactory } from "./impl.js";
|
||||
// import { CollectorFactory } from "./types.js";
|
||||
|
||||
// const toArrayCollectorFactory = new ToArrayCollectorFactory<any>();
|
||||
|
||||
// export function toArray<TElement>(): CollectorFactory<TElement, TElement[]> {
|
||||
// return toArrayCollectorFactory;
|
||||
// }
|
||||
|
||||
// export function toObject<TElement, TKey extends PropertyKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): CollectorFactory<TElement, Record<TKey, TValue>> {
|
||||
// return () => toObjectCollectorFactory<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
// }
|
||||
|
||||
// export function toMap<TElement, TKey, TValue>(keySelector: Converter<TElement, TKey>, valueSelector: Converter<TElement, TValue>): CollectorFactory<TElement, Map<TKey, TValue>> {
|
||||
// return () => new ToMapCollectorInstance<TElement, TKey, TValue>(keySelector, valueSelector);
|
||||
// }
|
||||
|
||||
// export function toSet<TElement>(): CollectorFactory<TElement, Set<TElement>> {
|
||||
// return () => new ToSetCollectorInstance<TElement>();
|
||||
// }
|
||||
|
||||
// export function join(delimiter?: string, prefix?: string, suffix?: string): CollectorFactory<any, string> {
|
||||
// return () => new JoinCollectorInstance(delimiter, prefix, suffix);
|
||||
// }
|
||||
|
||||
// function sumCollectorFactory() {
|
||||
// return new SumCollectorInstance();
|
||||
// }
|
||||
|
||||
// export function sum(): CollectorFactory<number, number> {
|
||||
// return sumCollectorFactory;
|
||||
// }
|
||||
|
||||
// function bigintSumCollectorFactory() {
|
||||
// return new BigIntSumCollectorInstance();
|
||||
// }
|
||||
|
||||
// export function bigintSum(): CollectorFactory<bigint | number, bigint> {
|
||||
// return bigintSumCollectorFactory;
|
||||
// }
|
||||
|
||||
// function averageCollectorFactory() {
|
||||
// return new AverageCollectorInstance();
|
||||
// }
|
||||
|
||||
// export function average(): CollectorFactory<number, number> {
|
||||
// return averageCollectorFactory;
|
||||
// }
|
||||
|
||||
// function bigintAverageCollectorFactory() {
|
||||
// return new BigIntAverageCollectorInstance();
|
||||
// }
|
||||
|
||||
// export function bigintAverage(): CollectorFactory<bigint, bigint> {
|
||||
// return bigintAverageCollectorFactory;
|
||||
// }
|
||||
8
src/collector/v2/types.ts
Normal file
8
src/collector/v2/types.ts
Normal file
@@ -0,0 +1,8 @@
|
||||
// export interface CollectorFactory<TElement, TResult> {
|
||||
// initialize(): CollectorInstance<TElement, TResult>;
|
||||
// }
|
||||
|
||||
// export interface CollectorInstance<TElement, TResult> {
|
||||
// accumulate(element: TElement): void;
|
||||
// finalize(): TResult;
|
||||
// }
|
||||
245
src/comparer/async.ts
Normal file
245
src/comparer/async.ts
Normal file
@@ -0,0 +1,245 @@
|
||||
import { MaybeAsyncConverter } from "../types.js";
|
||||
import { Nullable } from "../utils.js";
|
||||
import { AsyncComparer, MaybeAsyncComparisonOrComparer, Comparer, MaybeAsyncComparison, AsyncComparison } from "./types.js";
|
||||
|
||||
export function isAsyncComparer<T>(obj: any): obj is AsyncComparer<T> {
|
||||
return obj instanceof BaseAsyncComparer;
|
||||
}
|
||||
|
||||
export function asAsyncComparer<T>(comparer: MaybeAsyncComparisonOrComparer<T>): AsyncComparer<T> {
|
||||
return typeof comparer === "function" ? createAsyncComparer(comparer) : isAsyncComparer<T>(comparer) ? comparer : new WrappedAsyncComparer(comparer);
|
||||
}
|
||||
|
||||
export function fromSync<T>(comparer: Comparer<T>): AsyncComparer<T> {
|
||||
return new WrappedAsyncComparer(comparer);
|
||||
}
|
||||
|
||||
export function createAsyncComparer<T>(comparison: MaybeAsyncComparison<T>): AsyncComparer<T> {
|
||||
return new SimpleAsyncComparer(comparison);
|
||||
}
|
||||
|
||||
export function createAsyncComparerUsing<T, U>(projection: MaybeAsyncConverter<T, U>, comparison?: MaybeAsyncComparisonOrComparer<U>): AsyncComparer<T> {
|
||||
return new MappedAsyncComparer(projection, comparison);
|
||||
}
|
||||
|
||||
export function combineNullableAsyncComparers<T>(comparers: Nullable<MaybeAsyncComparisonOrComparer<T>>[]): AsyncComparer<T> | undefined {
|
||||
let result = defaultAsyncComparer;
|
||||
|
||||
for (const comparer of comparers) {
|
||||
if (!comparer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = result.then(asAsyncComparer(comparer));
|
||||
}
|
||||
|
||||
return result === defaultAsyncComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseAsyncComparer<T> implements AsyncComparer<T> {
|
||||
#cachedBoundComparison: AsyncComparison<T> | undefined;
|
||||
|
||||
public abstract compare(a: T, b: T): Promise<number>;
|
||||
|
||||
public comparison(): AsyncComparison<T> {
|
||||
return this.#cachedBoundComparison ??= this.compare.bind(this);
|
||||
}
|
||||
|
||||
public reverse(): AsyncComparer<T> {
|
||||
return new ReversedAsyncComparer(this);
|
||||
}
|
||||
|
||||
public then(comparer: AsyncComparer<T>): AsyncComparer<T> {
|
||||
return new ThenAsyncComparer(this, comparer);
|
||||
}
|
||||
|
||||
public thenCompare(comparison: MaybeAsyncComparison<T>): AsyncComparer<T> {
|
||||
return this.then(createAsyncComparer(comparison));
|
||||
}
|
||||
|
||||
public thenCompareUsing<U>(projection: MaybeAsyncConverter<T, U>, comparer?: MaybeAsyncComparisonOrComparer<U>): AsyncComparer<T> {
|
||||
return this.then(createAsyncComparerUsing(projection, comparer));
|
||||
}
|
||||
|
||||
public nullAwareComparer(): AsyncComparer<Nullable<T>> {
|
||||
return new NullAwareAsyncComparer(this);
|
||||
}
|
||||
}
|
||||
|
||||
class WrappedAsyncComparer<T> extends BaseAsyncComparer<T> {
|
||||
readonly #base: Comparer<T>;
|
||||
|
||||
constructor(base: Comparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = base;
|
||||
}
|
||||
|
||||
public override async compare(a: T, b: T) {
|
||||
return this.#base.compare(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleAsyncComparer<T> extends BaseAsyncComparer<T> {
|
||||
readonly #comparison: MaybeAsyncComparison<T>;
|
||||
|
||||
public constructor(comparison: MaybeAsyncComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#comparison = comparison;
|
||||
}
|
||||
|
||||
public async compare(a: T, b: T) {
|
||||
return await this.#comparison(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
class MappedAsyncComparer<T, U> extends BaseAsyncComparer<T> {
|
||||
readonly #projection: MaybeAsyncConverter<T, U>;
|
||||
readonly #comparer: AsyncComparer<U>;
|
||||
|
||||
public constructor(projection: MaybeAsyncConverter<T, U>, comparer?: MaybeAsyncComparisonOrComparer<U>) {
|
||||
super();
|
||||
|
||||
this.#projection = projection;
|
||||
this.#comparer = comparer ? asAsyncComparer(comparer) : defaultAsyncComparer;
|
||||
}
|
||||
|
||||
public async compare(a: T, b: T) {
|
||||
return await this.#comparer.compare(await this.#projection(a), await this.#projection(b));
|
||||
}
|
||||
}
|
||||
|
||||
class ReversedAsyncComparer<T> extends BaseAsyncComparer<T> {
|
||||
readonly #base: AsyncComparer<T>;
|
||||
|
||||
public constructor(base: AsyncComparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = base;
|
||||
}
|
||||
|
||||
public async compare(a: T, b: T) {
|
||||
return await this.#base.compare(b, a);
|
||||
}
|
||||
|
||||
public override reverse() {
|
||||
return this.#base;
|
||||
}
|
||||
}
|
||||
|
||||
class ThenAsyncComparer<T> extends BaseAsyncComparer<T> {
|
||||
readonly #base: AsyncComparer<T>;
|
||||
readonly #comparer: AsyncComparer<T>;
|
||||
|
||||
public constructor(base: AsyncComparer<T>, comparer: AsyncComparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = base;
|
||||
this.#comparer = comparer;
|
||||
}
|
||||
|
||||
public async compare(a: T, b: T) {
|
||||
return await this.#base.compare(a, b) || await this.#comparer.compare(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultAsyncComparer: AsyncComparer<any> = new class DefaultAsyncComparer extends BaseAsyncComparer<any> {
|
||||
public override async compare(a: any, b: any): Promise<number> {
|
||||
if (a === undefined) {
|
||||
if (b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const aStr = `${a}`, bStr = `${b}`;
|
||||
|
||||
return aStr > bStr ? 1 : aStr < bStr ? -1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
export function getDefaultAsyncComparer<T>(): AsyncComparer<T> {
|
||||
return defaultAsyncComparer;
|
||||
}
|
||||
|
||||
class NullAwareAsyncComparer<T> extends BaseAsyncComparer<Nullable<T>> {
|
||||
readonly #base: AsyncComparer<T>;
|
||||
|
||||
constructor(baseComparer: AsyncComparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = baseComparer;
|
||||
}
|
||||
|
||||
public override async compare(a: Nullable<T>, b: Nullable<T>): Promise<number> {
|
||||
if (a === undefined) {
|
||||
if (b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a === null) {
|
||||
if (b === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return await this.#base.compare(a, b);
|
||||
}
|
||||
|
||||
public override nullAwareComparer(): AsyncComparer<Nullable<T>> {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export function nullAwareComparer<T>(baseComparer: AsyncComparer<T>): AsyncComparer<Nullable<T>> {
|
||||
return new NullAwareAsyncComparer(baseComparer);
|
||||
}
|
||||
|
||||
export const stringAsyncComparer: AsyncComparer<string> = new class StringAsyncComparer extends BaseAsyncComparer<string> {
|
||||
public override async compare(a: string, b: string): Promise<number> {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
};
|
||||
|
||||
export const numberAsyncComparer: AsyncComparer<number> = new class NumberAsyncComparer extends BaseAsyncComparer<number> {
|
||||
public override async compare(a: number, b: number): Promise<number> {
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
export const bigintAsyncComparer: AsyncComparer<bigint> = new class BigIntAsyncComparer extends BaseAsyncComparer<bigint> {
|
||||
public override async compare(a: bigint, b: bigint): Promise<number> {
|
||||
return Number(a - b);
|
||||
}
|
||||
};
|
||||
|
||||
export const booleanAsyncComparer: AsyncComparer<boolean> = new class BooleanAsyncComparer extends BaseAsyncComparer<boolean> {
|
||||
public override async compare(a: boolean, b: boolean): Promise<number> {
|
||||
return Number(a) - Number(b);
|
||||
}
|
||||
};
|
||||
|
||||
export const dateAsyncComparer: AsyncComparer<Date> = new class DateAsyncComparer extends BaseAsyncComparer<Date> {
|
||||
public override async compare(a: Date, b: Date): Promise<number> {
|
||||
return a.getTime() - b.getTime();
|
||||
}
|
||||
};
|
||||
244
src/comparer/sync.ts
Normal file
244
src/comparer/sync.ts
Normal file
@@ -0,0 +1,244 @@
|
||||
import { Converter } from "../types.js";
|
||||
import { Nullable } from "../utils.js";
|
||||
import { fromSync } from "./async.js";
|
||||
import { Comparer, ComparisonOrComparer, Comparison, AsyncComparer } from "./types.js";
|
||||
|
||||
export function isComparer<T>(obj: any): obj is Comparer<T> {
|
||||
return obj instanceof BaseComparer;
|
||||
}
|
||||
|
||||
export function asComparer<T>(comparer: ComparisonOrComparer<T>) {
|
||||
return typeof comparer === "function" ? createComparer(comparer) : comparer;
|
||||
}
|
||||
|
||||
export function asComparison<T>(comparer: ComparisonOrComparer<T>) {
|
||||
return typeof comparer === "function" ? comparer : comparer.comparison();
|
||||
}
|
||||
|
||||
export function createComparer<T>(comparison: Comparison<T>): Comparer<T> {
|
||||
return new SimpleComparer(comparison);
|
||||
}
|
||||
|
||||
export function createComparerUsing<T, U>(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>): Comparer<T> {
|
||||
return new MappedComparer(projection, comparison);
|
||||
}
|
||||
|
||||
export function reverseComparison<T>(comparison: Comparison<T>): Comparison<T> {
|
||||
return (a, b) => comparison(b, a);
|
||||
}
|
||||
|
||||
export function combineNullableComparers<T>(comparers: Nullable<ComparisonOrComparer<T>>[]) {
|
||||
let result = defaultComparer;
|
||||
|
||||
for (const comparer of comparers) {
|
||||
if (!comparer) {
|
||||
continue;
|
||||
}
|
||||
|
||||
result = result.then(asComparer(comparer));
|
||||
}
|
||||
|
||||
return result === defaultComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseComparer<T> implements Comparer<T> {
|
||||
#cachedBoundComparison: Comparison<T> | undefined;
|
||||
|
||||
public abstract compare(a: T, b: T): number;
|
||||
|
||||
public comparison(): Comparison<T> {
|
||||
return this.#cachedBoundComparison ??= this.compare.bind(this);
|
||||
}
|
||||
|
||||
public reverse(): Comparer<T> {
|
||||
return new ReversedComparer(this);
|
||||
}
|
||||
|
||||
public then(comparer: Comparer<T>): Comparer<T> {
|
||||
return new ThenComparer(this, comparer);
|
||||
}
|
||||
|
||||
public thenCompare(comparison: Comparison<T>): Comparer<T> {
|
||||
return this.then(createComparer(comparison));
|
||||
}
|
||||
|
||||
public thenCompareUsing<U>(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>): Comparer<T> {
|
||||
return this.then(createComparerUsing(projection, comparison));
|
||||
}
|
||||
|
||||
public toAsync(): AsyncComparer<T> {
|
||||
return fromSync<T>(this);
|
||||
}
|
||||
|
||||
public nullAwareComparer(): Comparer<Nullable<T>> {
|
||||
return new NullAwareComparer(this);
|
||||
}
|
||||
}
|
||||
|
||||
class SimpleComparer<T> extends BaseComparer<T> {
|
||||
readonly #comparison: Comparison<T>;
|
||||
|
||||
public constructor(comparison: Comparison<T>) {
|
||||
super();
|
||||
|
||||
this.#comparison = comparison;
|
||||
}
|
||||
|
||||
public override compare(a: T, b: T) {
|
||||
return this.#comparison(a, b);
|
||||
}
|
||||
|
||||
public override comparison() {
|
||||
return this.#comparison;
|
||||
}
|
||||
}
|
||||
|
||||
class MappedComparer<T, U> extends BaseComparer<T> {
|
||||
readonly #projection: Converter<T, U>;
|
||||
readonly #comparison: Comparer<U>;
|
||||
|
||||
public constructor(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>) {
|
||||
super();
|
||||
|
||||
this.#projection = projection;
|
||||
this.#comparison = comparison ? asComparer(comparison) : defaultComparer;
|
||||
}
|
||||
|
||||
public override compare(a: T, b: T) {
|
||||
return this.#comparison.compare(this.#projection(a), this.#projection(b));
|
||||
}
|
||||
}
|
||||
|
||||
class ReversedComparer<T> extends BaseComparer<T> {
|
||||
readonly #base: Comparer<T>;
|
||||
|
||||
public constructor(base: Comparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = base;
|
||||
}
|
||||
|
||||
public override compare(a: T, b: T): number {
|
||||
return this.#base.compare(b, a);
|
||||
}
|
||||
|
||||
public override reverse(): Comparer<T> {
|
||||
return this.#base;
|
||||
}
|
||||
}
|
||||
|
||||
class ThenComparer<T> extends BaseComparer<T> {
|
||||
readonly #base: Comparer<T>;
|
||||
readonly #comparer: Comparer<T>;
|
||||
|
||||
public constructor(base: Comparer<T>, comparer: Comparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = base;
|
||||
this.#comparer = comparer;
|
||||
}
|
||||
|
||||
public override compare(a: T, b: T) {
|
||||
return this.#base.compare(a, b) || this.#comparer.compare(a, b);
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultComparer: Comparer<any> = new class DefaultComparer extends BaseComparer<any> {
|
||||
public override compare(a: any, b: any): number {
|
||||
if (a === undefined) {
|
||||
if (b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const aStr = `${a}`, bStr = `${b}`;
|
||||
|
||||
return aStr > bStr ? 1 : aStr < bStr ? -1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
export function getDefaultComparer<T>(): Comparer<T> {
|
||||
return defaultComparer;
|
||||
}
|
||||
|
||||
class NullAwareComparer<T> extends BaseComparer<Nullable<T>> {
|
||||
readonly #base: Comparer<T>;
|
||||
|
||||
constructor(baseComparer: Comparer<T>) {
|
||||
super();
|
||||
|
||||
this.#base = baseComparer;
|
||||
}
|
||||
|
||||
public override compare(a: Nullable<T>, b: Nullable<T>): number {
|
||||
if (a === undefined) {
|
||||
if (b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (a === null) {
|
||||
if (b === null) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === null) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return this.#base.compare(a, b);
|
||||
}
|
||||
|
||||
public override nullAwareComparer(): Comparer<Nullable<T>> {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
export function nullAwareComparer<T>(baseComparer: Comparer<T>): Comparer<Nullable<T>> {
|
||||
return new NullAwareComparer(baseComparer);
|
||||
}
|
||||
|
||||
export const stringComparer: Comparer<string> = new class StringComparer extends BaseComparer<string> {
|
||||
public override compare(a: string, b: string): number {
|
||||
return a.localeCompare(b);
|
||||
}
|
||||
};
|
||||
|
||||
export const numberComparer: Comparer<number> = new class NumberComparer extends BaseComparer<number> {
|
||||
public override compare(a: number, b: number): number {
|
||||
return a - b;
|
||||
}
|
||||
};
|
||||
|
||||
export const bigintComparer: Comparer<bigint> = new class BigIntComparer extends BaseComparer<bigint> {
|
||||
public override compare(a: bigint, b: bigint): number {
|
||||
return Number(a - b);
|
||||
}
|
||||
};
|
||||
|
||||
export const booleanComparer: Comparer<boolean> = new class BooleanComparer extends BaseComparer<boolean> {
|
||||
public override compare(a: boolean, b: boolean): number {
|
||||
return Number(a) - Number(b);
|
||||
}
|
||||
};
|
||||
|
||||
export const dateComparer: Comparer<Date> = new class DateComparer extends BaseComparer<Date> {
|
||||
public override compare(a: Date, b: Date): number {
|
||||
return a.getTime() - b.getTime();
|
||||
}
|
||||
};
|
||||
35
src/comparer/types.ts
Normal file
35
src/comparer/types.ts
Normal file
@@ -0,0 +1,35 @@
|
||||
import { AsyncFunction, Converter, MaybeAsyncConverter, MaybeAsyncFunction } from "../types.js";
|
||||
import { Nullable } from "../utils.js";
|
||||
|
||||
export interface Comparer<T> {
|
||||
compare(a: T, b: T): number;
|
||||
comparison(): Comparison<T>;
|
||||
reverse(): Comparer<T>;
|
||||
then(comparer: Comparer<T>): Comparer<T>;
|
||||
thenCompare(comparison: Comparison<T>): Comparer<T>;
|
||||
thenCompareUsing<U>(projection: Converter<T, U>, comparison?: ComparisonOrComparer<U>): Comparer<T>;
|
||||
toAsync(): AsyncComparer<T>;
|
||||
nullAwareComparer(): Comparer<Nullable<T>>;
|
||||
}
|
||||
|
||||
export interface AsyncComparer<T> {
|
||||
compare(a: T, b: T): Promise<number>;
|
||||
comparison(): AsyncComparison<T>;
|
||||
reverse(): AsyncComparer<T>;
|
||||
then(comparer: AsyncComparer<T>): AsyncComparer<T>;
|
||||
thenCompare(comparison: AsyncComparison<T>): AsyncComparer<T>;
|
||||
thenCompareUsing<U>(projection: MaybeAsyncConverter<T, U>, comparison?: AsyncComparisonOrComparer<U>): AsyncComparer<T>;
|
||||
nullAwareComparer(): AsyncComparer<Nullable<T>>;
|
||||
}
|
||||
|
||||
export type Comparison<T> = (first: T, second: T) => number;
|
||||
export type ComparisonOrComparer<T> = Comparison<T> | Comparer<T>;
|
||||
export type Equater<T> = (first: T, second: T) => boolean;
|
||||
|
||||
export type AsyncComparison<T> = AsyncFunction<Comparison<T>>;
|
||||
export type MaybeAsyncComparison<T> = MaybeAsyncFunction<Comparison<T>>;
|
||||
export type AsyncComparisonOrComparer<T> = AsyncComparison<T> | AsyncComparer<T>;
|
||||
export type MaybeAsyncComparisonOrComparer<T> = MaybeAsyncComparison<T> | Comparer<T> | AsyncComparer<T>;
|
||||
export type AsyncEquater<T> = AsyncFunction<Equater<T>>;
|
||||
export type MaybeAsyncEquater<T> = MaybeAsyncFunction<Equater<T>>;
|
||||
|
||||
15
src/equality-comparer/index.ts
Normal file
15
src/equality-comparer/index.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
export function identity<T>(obj: T) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
export function looseEquals<T>(a: T, b: T) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
export function strictEquals<T>(a: T, b: T) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
export function sameValue<T>(a: T, b: T) {
|
||||
return Object.is(a, b);
|
||||
}
|
||||
6
src/equality-comparer/types.ts
Normal file
6
src/equality-comparer/types.ts
Normal file
@@ -0,0 +1,6 @@
|
||||
import { AsyncFunction, MaybeAsyncFunction } from "../types.js";
|
||||
|
||||
export type EqualityComparison<T> = (first: T, second: T) => boolean;
|
||||
|
||||
export type AsyncEqualityComparison<T> = AsyncFunction<EqualityComparison<T>>;
|
||||
export type MaybeAsyncEqualityComparison<T> = MaybeAsyncFunction<EqualityComparison<T>>;
|
||||
@@ -1,15 +1,19 @@
|
||||
import { Equater, MaybeAsyncEquater } from "./types.js";
|
||||
import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js";
|
||||
import { MaybeAsyncIterable } from "./types.js";
|
||||
|
||||
export interface EqualityMap<K, V> extends Iterable<[K, V]> {
|
||||
export type Entry<K, V> = [key: K, value: V];
|
||||
|
||||
export interface EqualityMap<K, V> extends Iterable<Entry<K, V>> {
|
||||
readonly size: number;
|
||||
get(key: K): V | undefined;
|
||||
set(key: K, value: V): V | undefined;
|
||||
setAll(entries: Iterable<Entry<K, V>>): void;
|
||||
contains(key: K): boolean;
|
||||
remove(key: K): V | undefined;
|
||||
clear(): void;
|
||||
keys(): IterableIterator<K>;
|
||||
values(): IterableIterator<V>;
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
entries(): IterableIterator<Entry<K, V>>;
|
||||
}
|
||||
|
||||
class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
@@ -29,6 +33,12 @@ class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
return existing;
|
||||
}
|
||||
|
||||
setAll(entries: Iterable<Entry<K, V>>) {
|
||||
for (const [key, value] of entries) {
|
||||
this.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
contains(key: K) {
|
||||
return this.#map.has(key);
|
||||
}
|
||||
@@ -61,10 +71,10 @@ class NativeEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
}
|
||||
|
||||
class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
readonly #list: [K, V][] = [];
|
||||
readonly #keyComparer: Equater<K>;
|
||||
readonly #list: Entry<K, V>[] = [];
|
||||
readonly #keyComparer: EqualityComparison<K>;
|
||||
|
||||
constructor(keyComparer: Equater<K>) {
|
||||
constructor(keyComparer: EqualityComparison<K>) {
|
||||
this.#keyComparer = keyComparer;
|
||||
}
|
||||
|
||||
@@ -96,6 +106,12 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
setAll(entries: Iterable<Entry<K, V>>) {
|
||||
for (const [key, value] of entries) {
|
||||
this.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
contains(key: K) {
|
||||
for (const entry of this.#list) {
|
||||
if (this.#keyComparer(key, entry[0])) {
|
||||
@@ -139,25 +155,26 @@ class CustomEqualityMap<K, V> implements EqualityMap<K, V> {
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry.slice() as [K, V]; // no entry mutation allowed!
|
||||
yield entry.slice() as Entry<K, V>; // no entry mutation allowed!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createEqualityMap<K, V>(keyComparer?: Equater<K>): EqualityMap<K, V> {
|
||||
export function createEqualityMap<K, V>(keyComparer?: EqualityComparison<K>): EqualityMap<K, V> {
|
||||
return keyComparer ? new CustomEqualityMap<K, V>(keyComparer) : new NativeEqualityMap<K, V>();
|
||||
}
|
||||
|
||||
export interface AsyncEqualityMap<K, V> extends Iterable<[K, V]> {
|
||||
export interface AsyncEqualityMap<K, V> extends Iterable<Entry<K, V>> {
|
||||
readonly size: number;
|
||||
get(key: K): Promise<V | undefined>;
|
||||
set(key: K, value: V): Promise<V | undefined>;
|
||||
setAll(entries: MaybeAsyncIterable<Entry<K, V>>): Promise<void>;
|
||||
contains(key: K): Promise<boolean>;
|
||||
remove(key: K): Promise<V | undefined>;
|
||||
clear(): void;
|
||||
keys(): IterableIterator<K>;
|
||||
values(): IterableIterator<V>;
|
||||
entries(): IterableIterator<[K, V]>;
|
||||
entries(): IterableIterator<Entry<K, V>>;
|
||||
}
|
||||
|
||||
class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
@@ -177,6 +194,12 @@ class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
return existing;
|
||||
}
|
||||
|
||||
async setAll(entries: MaybeAsyncIterable<Entry<K, V>>) {
|
||||
for await (const [key, value] of entries) {
|
||||
await this.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
async contains(key: K) {
|
||||
return this.#map.has(key);
|
||||
}
|
||||
@@ -209,10 +232,10 @@ class NativeAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
}
|
||||
|
||||
class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
readonly #list: [K, V][] = [];
|
||||
readonly #keyComparer: MaybeAsyncEquater<K>;
|
||||
readonly #list: Entry<K, V>[] = [];
|
||||
readonly #keyComparer: MaybeAsyncEqualityComparison<K>;
|
||||
|
||||
constructor(keyComparer: MaybeAsyncEquater<K>) {
|
||||
constructor(keyComparer: MaybeAsyncEqualityComparison<K>) {
|
||||
this.#keyComparer = keyComparer;
|
||||
}
|
||||
|
||||
@@ -244,6 +267,12 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async setAll(entries: MaybeAsyncIterable<Entry<K, V>>) {
|
||||
for await (const [key, value] of entries) {
|
||||
await this.set(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
async contains(key: K) {
|
||||
for (const entry of this.#list) {
|
||||
if (await this.#keyComparer(key, entry[0])) {
|
||||
@@ -287,11 +316,11 @@ class CustomAsyncEqualityMap<K, V> implements AsyncEqualityMap<K, V> {
|
||||
|
||||
*[Symbol.iterator]() {
|
||||
for (const entry of this.#list) {
|
||||
yield entry.slice() as [K, V]; // no entry mutation allowed!
|
||||
yield entry.slice() as Entry<K, V>; // no entry mutation allowed!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function createAsyncEqualityMap<K, V>(keyComparer?: MaybeAsyncEquater<K>): AsyncEqualityMap<K, V> {
|
||||
export function createAsyncEqualityMap<K, V>(keyComparer?: MaybeAsyncEqualityComparison<K>): AsyncEqualityMap<K, V> {
|
||||
return keyComparer ? new CustomAsyncEqualityMap<K, V>(keyComparer) : new NativeAsyncEqualityMap<K, V>();
|
||||
}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import { Equater, MaybeAsyncEquater } from "./types.js";
|
||||
import { EqualityComparison, MaybeAsyncEqualityComparison } from "./equality-comparer/types.js";
|
||||
import { MaybeAsyncIterable } from "./types.js";
|
||||
|
||||
export interface EqualitySet<T> extends Iterable<T> {
|
||||
readonly size: number;
|
||||
add(obj: T): boolean;
|
||||
contains(obj: T): boolean;
|
||||
remove(obj: T): boolean;
|
||||
add(value: T): boolean;
|
||||
addAll(values: Iterable<T>): number;
|
||||
contains(value: T): boolean;
|
||||
remove(value: T): boolean;
|
||||
clear(): void;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
@@ -16,18 +18,30 @@ class NativeEqualitySet<T> implements EqualitySet<T> {
|
||||
return this.#set.size;
|
||||
}
|
||||
|
||||
add(obj: T) {
|
||||
const exists = this.contains(obj);
|
||||
this.#set.add(obj);
|
||||
add(value: T) {
|
||||
const exists = this.contains(value);
|
||||
this.#set.add(value);
|
||||
return !exists;
|
||||
}
|
||||
|
||||
contains(obj: T) {
|
||||
return this.#set.has(obj);
|
||||
addAll(values: Iterable<T>) {
|
||||
let result = 0;
|
||||
|
||||
for (const value of values) {
|
||||
if (this.add(value)) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
remove(obj: T) {
|
||||
return this.#set.delete(obj);
|
||||
contains(value: T) {
|
||||
return this.#set.has(value);
|
||||
}
|
||||
|
||||
remove(value: T) {
|
||||
return this.#set.delete(value);
|
||||
}
|
||||
|
||||
clear() {
|
||||
@@ -45,9 +59,9 @@ class NativeEqualitySet<T> implements EqualitySet<T> {
|
||||
|
||||
class CustomEqualitySet<T> implements EqualitySet<T> {
|
||||
readonly #list: T[] = [];
|
||||
readonly #equater: Equater<T>;
|
||||
readonly #equater: EqualityComparison<T>;
|
||||
|
||||
constructor(equater: Equater<T>) {
|
||||
constructor(equater: EqualityComparison<T>) {
|
||||
this.#equater = equater;
|
||||
}
|
||||
|
||||
@@ -55,19 +69,31 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
|
||||
return this.#list.length;
|
||||
}
|
||||
|
||||
add(obj: T) {
|
||||
if (this.contains(obj)) {
|
||||
add(value: T) {
|
||||
if (this.contains(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.#list.push(obj);
|
||||
this.#list.push(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
contains(obj: T) {
|
||||
addAll(values: Iterable<T>) {
|
||||
let result = 0;
|
||||
|
||||
for (const value of values) {
|
||||
if (this.add(value)) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
contains(value: T) {
|
||||
for (const val of this.#list) {
|
||||
if (this.#equater(obj, val)) {
|
||||
if (this.#equater(value, val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -75,11 +101,11 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
remove(obj: T) {
|
||||
remove(value: T) {
|
||||
const length = this.#list.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (this.#equater(obj, this.#list[i])) {
|
||||
if (this.#equater(value, this.#list[i])) {
|
||||
this.#list.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
@@ -101,15 +127,16 @@ class CustomEqualitySet<T> implements EqualitySet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function createEqualitySet<T>(equater?: Equater<T>): EqualitySet<T> {
|
||||
export function createEqualitySet<T>(equater?: EqualityComparison<T>): EqualitySet<T> {
|
||||
return equater ? new CustomEqualitySet(equater) : new NativeEqualitySet<T>();
|
||||
}
|
||||
|
||||
export interface AsyncEqualitySet<T> extends Iterable<T> {
|
||||
readonly size: number;
|
||||
add(obj: T): Promise<boolean>;
|
||||
contains(obj: T): Promise<boolean>;
|
||||
remove(obj: T): Promise<boolean>;
|
||||
add(value: T): Promise<boolean>;
|
||||
addAll(values: MaybeAsyncIterable<T>): Promise<number>;
|
||||
contains(value: T): Promise<boolean>;
|
||||
remove(value: T): Promise<boolean>;
|
||||
clear(): void;
|
||||
values(): IterableIterator<T>;
|
||||
}
|
||||
@@ -121,18 +148,30 @@ class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
return this.#set.size;
|
||||
}
|
||||
|
||||
async add(obj: T) {
|
||||
const exists = await this.contains(obj);
|
||||
this.#set.add(obj);
|
||||
async add(value: T) {
|
||||
const exists = await this.contains(value);
|
||||
this.#set.add(value);
|
||||
return !exists;
|
||||
}
|
||||
|
||||
async contains(obj: T) {
|
||||
return this.#set.has(obj);
|
||||
async addAll(values: MaybeAsyncIterable<T>) {
|
||||
let result = 0;
|
||||
|
||||
for await (const value of values) {
|
||||
if (await this.add(value)) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async remove(obj: T) {
|
||||
return this.#set.delete(obj);
|
||||
async contains(value: T) {
|
||||
return this.#set.has(value);
|
||||
}
|
||||
|
||||
async remove(value: T) {
|
||||
return this.#set.delete(value);
|
||||
}
|
||||
|
||||
clear() {
|
||||
@@ -150,9 +189,9 @@ class NativeAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
|
||||
class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
readonly #list: T[] = [];
|
||||
readonly #equater: MaybeAsyncEquater<T>;
|
||||
readonly #equater: MaybeAsyncEqualityComparison<T>;
|
||||
|
||||
constructor(equater: MaybeAsyncEquater<T>) {
|
||||
constructor(equater: MaybeAsyncEqualityComparison<T>) {
|
||||
this.#equater = equater;
|
||||
}
|
||||
|
||||
@@ -160,19 +199,31 @@ class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
return this.#list.length;
|
||||
}
|
||||
|
||||
async add(obj: T) {
|
||||
if (await this.contains(obj)) {
|
||||
async add(value: T) {
|
||||
if (await this.contains(value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this.#list.push(obj);
|
||||
this.#list.push(value);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
async contains(obj: T) {
|
||||
async addAll(values: MaybeAsyncIterable<T>) {
|
||||
let result = 0;
|
||||
|
||||
for await (const value of values) {
|
||||
if (await this.add(value)) {
|
||||
result++;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
async contains(value: T) {
|
||||
for (const val of this.#list) {
|
||||
if (await this.#equater(obj, val)) {
|
||||
if (await this.#equater(value, val)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -180,11 +231,11 @@ class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
return false;
|
||||
}
|
||||
|
||||
async remove(obj: T) {
|
||||
async remove(value: T) {
|
||||
const length = this.#list.length;
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (await this.#equater(obj, this.#list[i])) {
|
||||
if (await this.#equater(value, this.#list[i])) {
|
||||
this.#list.splice(i, 1);
|
||||
return true;
|
||||
}
|
||||
@@ -206,6 +257,6 @@ class CustomAsyncEqualitySet<T> implements AsyncEqualitySet<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export function createAsyncEqualitySet<T>(equater?: MaybeAsyncEquater<T>): AsyncEqualitySet<T> {
|
||||
export function createAsyncEqualitySet<T>(equater?: MaybeAsyncEqualityComparison<T>): AsyncEqualitySet<T> {
|
||||
return equater ? new CustomAsyncEqualitySet(equater) : new NativeAsyncEqualitySet<T>();
|
||||
}
|
||||
|
||||
11
src/index.ts
11
src/index.ts
@@ -1,7 +1,7 @@
|
||||
export { BaseSequence, DelegatedSequence } from "./sync/impl.js";
|
||||
export { BaseSequence } from "./sync/impl.js";
|
||||
export * as Sequences from "./sync/index.js";
|
||||
export * from "./sync/types.js";
|
||||
export { BaseAsyncSequence, DelegatedAsyncSequence } from "./async/impl.js";
|
||||
export { BaseAsyncSequence } from "./async/impl.js";
|
||||
export * as AsyncSequences from "./async/index.js";
|
||||
export * from "./async/types.js";
|
||||
export * as Collectors from "./collector/index.js";
|
||||
@@ -10,3 +10,10 @@ export * as BitArrays from "./bitarray/index.js";
|
||||
export * from "./bitarray/types.js";
|
||||
export * as Random from "./random/index.js";
|
||||
export * from "./random/types.js";
|
||||
export { BaseComparer } from "./comparer/sync.js";
|
||||
export * as Comparers from "./comparer/sync.js";
|
||||
export { BaseAsyncComparer } from "./comparer/async.js";
|
||||
export * as AsyncComparers from "./comparer/async.js";
|
||||
export * from "./comparer/types.js";
|
||||
export * as EqualityComparers from "./equality-comparer/index.js";
|
||||
export * from "./equality-comparer/types.js";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import { MaybeAsyncComparer } from "./types.js";
|
||||
import { reverseAsyncComparer } from "./utils.js";
|
||||
import { asAsyncComparer } from "./comparer/async.js";
|
||||
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "./comparer/types.js";
|
||||
|
||||
export interface AsyncSorter {
|
||||
sort<T>(array: T[], descending: boolean, comparer: MaybeAsyncComparer<T>): Promise<void>;
|
||||
sort<T>(array: T[], descending: boolean, comparer: MaybeAsyncComparisonOrComparer<T>): Promise<void>;
|
||||
}
|
||||
|
||||
function swap(array: any[], i: number, j: number) {
|
||||
@@ -12,20 +12,26 @@ function swap(array: any[], i: number, j: number) {
|
||||
}
|
||||
|
||||
abstract class BaseAsyncSorter implements AsyncSorter {
|
||||
async sort<T>(array: T[], descending: boolean, comparer: MaybeAsyncComparer<T>) {
|
||||
await this._sort(array, descending ? reverseAsyncComparer(comparer) : comparer);
|
||||
async sort<T>(array: T[], descending: boolean, comparer: MaybeAsyncComparisonOrComparer<T>) {
|
||||
comparer = asAsyncComparer(comparer);
|
||||
|
||||
if (descending) {
|
||||
comparer = comparer.reverse();
|
||||
}
|
||||
|
||||
await this._sort(array, comparer);
|
||||
}
|
||||
|
||||
protected abstract _sort<T>(array: T[], comparer: MaybeAsyncComparer<T>): Promise<void>;
|
||||
protected abstract _sort<T>(array: T[], comparer: AsyncComparer<T>): Promise<void>;
|
||||
}
|
||||
|
||||
class InsertionSorter extends BaseAsyncSorter {
|
||||
protected override async _sort<T>(array: T[], comparer: MaybeAsyncComparer<T>) {
|
||||
export const insertionSorter: AsyncSorter = new class InsertionSorter extends BaseAsyncSorter {
|
||||
protected override async _sort<T>(array: T[], comparer: AsyncComparer<T>) {
|
||||
for (let i = 1; i < array.length; i++) {
|
||||
const obj = array[i];
|
||||
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
if (await comparer(obj, array[j]) < 0) {
|
||||
if (await comparer.compare(obj, array[j]) < 0) {
|
||||
for (let k = i; k > j; k--) {
|
||||
swap(array, k - 1, k);
|
||||
}
|
||||
@@ -35,10 +41,10 @@ class InsertionSorter extends BaseAsyncSorter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class SelectionSorter extends BaseAsyncSorter {
|
||||
protected async _sort<T>(array: T[], comparer: MaybeAsyncComparer<T>) {
|
||||
export const selectionSorter: AsyncSorter = new class SelectionSorter extends BaseAsyncSorter {
|
||||
protected async _sort<T>(array: T[], comparer: AsyncComparer<T>) {
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
let smallest = array[i];
|
||||
let smallestIndex = i;
|
||||
@@ -46,7 +52,7 @@ class SelectionSorter extends BaseAsyncSorter {
|
||||
for (let j = i; j < array.length; j++) {
|
||||
const current = array[j];
|
||||
|
||||
if (await comparer(current, smallest) < 0) {
|
||||
if (await comparer.compare(current, smallest) < 0) {
|
||||
smallest = current;
|
||||
smallestIndex = j;
|
||||
}
|
||||
@@ -57,10 +63,10 @@ class SelectionSorter extends BaseAsyncSorter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class BubbleSorter extends BaseAsyncSorter {
|
||||
protected async _sort<T>(array: T[], comparer: MaybeAsyncComparer<T>) {
|
||||
export const bubbleSorter: AsyncSorter = new class BubbleSorter extends BaseAsyncSorter {
|
||||
protected async _sort<T>(array: T[], comparer: AsyncComparer<T>) {
|
||||
const length = array.length;
|
||||
|
||||
for (let k = length - 2; k >= 0; k--) {
|
||||
@@ -70,7 +76,7 @@ class BubbleSorter extends BaseAsyncSorter {
|
||||
const j = i + 1;
|
||||
const a = array[i], b = array[j];
|
||||
|
||||
if (await comparer(a, b) > 0) {
|
||||
if (await comparer.compare(a, b) > 0) {
|
||||
swap(array, i, j);
|
||||
hasSwaped = true;
|
||||
}
|
||||
@@ -81,8 +87,4 @@ class BubbleSorter extends BaseAsyncSorter {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const insertionSorter: AsyncSorter = new InsertionSorter();
|
||||
export const selectionSorter: AsyncSorter = new SelectionSorter();
|
||||
export const bubbleSorter: AsyncSorter = new BubbleSorter();
|
||||
};
|
||||
|
||||
373
src/sync/impl.ts
373
src/sync/impl.ts
@@ -1,14 +1,17 @@
|
||||
import { BaseAsyncSequence } from "../async/impl.js";
|
||||
import { AsyncSequence } from "../async/types.js";
|
||||
import { Collector } from "../collector/types.js";
|
||||
import { asComparer, combineNullableComparers, createComparerUsing, defaultComparer } from "../comparer/sync.js";
|
||||
import { ComparisonOrComparer, Comparer } from "../comparer/types.js";
|
||||
import { strictEquals, identity } from "../equality-comparer/index.js";
|
||||
import { EqualityComparison } from "../equality-comparer/types.js";
|
||||
import { createEqualityMap } from "../equality-map.js";
|
||||
import { createEqualitySet } from "../equality-set.js";
|
||||
import { createQueue } from "../queue.js";
|
||||
import { getRandomElement } from "../random/index.js";
|
||||
import { RandomOptions } from "../random/types.js";
|
||||
import { AnyPredicate, Converter, FilterPredicate, Equater, BiConverter, Accumulator, Comparer, Action } from "../types.js";
|
||||
import { strictEquals, identity, operatorCompare, reverseComparer, asIterable, defaultArrayComparer, combineComparers } from "../utils.js";
|
||||
import { array, empty } from "./index.js";
|
||||
import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js";
|
||||
import { array, empty, wrap } from "./index.js";
|
||||
import { Sequence, GroupedSequence, OrderedSequence, SequencePipeline } from "./types.js";
|
||||
|
||||
export class SequenceMarker { }
|
||||
@@ -36,29 +39,29 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
return new SelectSequence<TElement, TResult>(this, converter);
|
||||
}
|
||||
|
||||
selectMany<TResult>(converter: Converter<TElement, Sequence<TResult>>): Sequence<TResult> {
|
||||
selectMany<TResult>(converter: Converter<TElement, Iterable<TResult>>): Sequence<TResult> {
|
||||
return new SelectManySequence<TElement, TResult>(this, converter);
|
||||
}
|
||||
|
||||
where<TFiltered extends TElement>(predicate: FilterPredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where(predicate: AnyPredicate<TElement>): Sequence<TElement>;
|
||||
where(predicate: any) {
|
||||
return new WhereSequence<TElement, any>(this, predicate);
|
||||
}
|
||||
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyComparer?: Equater<TKey>): Sequence<GroupedSequence<TKey, TResult>> {
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TResult>> {
|
||||
return new GroupBySequence<TElement, TKey, TResult>(this, keySelector, elementSelector, keyComparer);
|
||||
}
|
||||
|
||||
join<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: Equater<TKey>): Sequence<TResult> {
|
||||
return new JoinSequence<TElement, TOther, TKey, TResult>(this, sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult> {
|
||||
return new JoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Sequence<TOther>, TResult>, keyComparer?: Equater<TKey>): Sequence<TResult> {
|
||||
return new GroupJoinSequence<TElement, TOther, TKey, TResult>(this, sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult> {
|
||||
return new GroupJoinSequence<TElement, TOther, TKey, TResult>(this, wrap(sequence), firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
contains(obj: TElement, equater?: Equater<TElement>) {
|
||||
contains(obj: TElement, equater?: EqualityComparison<TElement>) {
|
||||
if (!equater) {
|
||||
equater = strictEquals;
|
||||
}
|
||||
@@ -72,13 +75,15 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
return false;
|
||||
}
|
||||
|
||||
sequenceEquals(sequence: Sequence<TElement>, equater?: Equater<TElement>) {
|
||||
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
|
||||
if (this === sequence) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const other = wrap(sequence);
|
||||
|
||||
const thisCount = this.nonEnumeratedCount();
|
||||
const thatCount = sequence.nonEnumeratedCount();
|
||||
const thatCount = other.nonEnumeratedCount();
|
||||
|
||||
if (thisCount >= 0 && thatCount >= 0 && thisCount !== thatCount) {
|
||||
return false;
|
||||
@@ -89,7 +94,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
}
|
||||
|
||||
const thisIterator = this.iterator();
|
||||
const thatIterator = sequence.iterator();
|
||||
const thatIterator = other.iterator();
|
||||
|
||||
while (true) {
|
||||
const thisNext = thisIterator.next();
|
||||
@@ -117,11 +122,11 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
return new PrependSequence<TElement>(this, obj);
|
||||
}
|
||||
|
||||
remove(obj: TElement, all?: boolean, equater?: Equater<TElement>): Sequence<TElement> {
|
||||
remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>): Sequence<TElement> {
|
||||
return new RemoveSequence<TElement>(this, obj, all, equater);
|
||||
}
|
||||
|
||||
concat(...sequences: Sequence<TElement>[]) {
|
||||
concat(...sequences: Iterable<TElement>[]) {
|
||||
if (sequences.length === 0) {
|
||||
return this;
|
||||
}
|
||||
@@ -129,7 +134,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
const arr: Sequence<TElement>[] = [this];
|
||||
|
||||
for (const sequence of sequences) {
|
||||
arr.push(sequence);
|
||||
arr.push(wrap(sequence));
|
||||
}
|
||||
|
||||
return new ConcatSequence(arr);
|
||||
@@ -400,7 +405,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
return acc as unknown as TResult;
|
||||
}
|
||||
|
||||
#find<TResult>(sorter: AnyPredicate<number>, selector?: Converter<TElement, TResult>, comparer?: Comparer<TResult>) {
|
||||
#find<TResult>(sorter: AnyPredicate<number>, selector?: Converter<TElement, TResult>, comparer?: ComparisonOrComparer<TResult>) {
|
||||
const iterator = this.iterator();
|
||||
|
||||
let next = iterator.next();
|
||||
@@ -413,9 +418,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
selector = identity as Converter<TElement, TResult>;
|
||||
}
|
||||
|
||||
if (!comparer) {
|
||||
comparer = operatorCompare;
|
||||
}
|
||||
comparer = comparer ? asComparer(comparer) : defaultComparer;
|
||||
|
||||
let result = next.value;
|
||||
let convertedResult = selector(result);
|
||||
@@ -430,7 +433,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
const value = next.value;
|
||||
const convertedValue = selector(value);
|
||||
|
||||
if (sorter(comparer(convertedResult, convertedValue))) {
|
||||
if (sorter(comparer.compare(convertedResult, convertedValue))) {
|
||||
result = value;
|
||||
convertedResult = convertedValue;
|
||||
}
|
||||
@@ -439,23 +442,23 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
return result;
|
||||
}
|
||||
|
||||
min(comparer?: Comparer<TElement>) {
|
||||
min(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#find(x => x > 0, undefined, comparer);
|
||||
}
|
||||
|
||||
minBy<TBy>(converter: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
minBy<TBy>(converter: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#find(x => x > 0, converter, comparer);
|
||||
}
|
||||
|
||||
max(comparer?: Comparer<TElement>) {
|
||||
max(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#find(x => x < 0, undefined, comparer);
|
||||
}
|
||||
|
||||
maxBy<TBy>(converter: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
maxBy<TBy>(converter: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#find(x => x < 0, converter, comparer);
|
||||
}
|
||||
|
||||
#findBounds<TResult>(selector?: Converter<TElement, TResult>, comparer?: Comparer<TResult>) {
|
||||
#findBounds<TResult>(selector?: Converter<TElement, TResult>, comparer?: ComparisonOrComparer<TResult>): [min: TElement, max: TElement] {
|
||||
const iterator = this.iterator();
|
||||
|
||||
let next = iterator.next();
|
||||
@@ -468,9 +471,7 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
selector = identity as Converter<TElement, TResult>;
|
||||
}
|
||||
|
||||
if (!comparer) {
|
||||
comparer = operatorCompare;
|
||||
}
|
||||
comparer = comparer ? asComparer(comparer) : defaultComparer;
|
||||
|
||||
let minBound = next.value, maxBound = minBound;
|
||||
let convertedMinBound = selector(minBound), convertedMaxBound = convertedMinBound;
|
||||
@@ -485,82 +486,82 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
const value = next.value;
|
||||
const convertedValue = selector(value);
|
||||
|
||||
if (comparer(convertedMinBound, convertedValue) > 0) {
|
||||
if (comparer.compare(convertedMinBound, convertedValue) > 0) {
|
||||
minBound = value;
|
||||
convertedMinBound = convertedValue;
|
||||
}
|
||||
|
||||
if (comparer(convertedMaxBound, convertedValue) < 0) {
|
||||
if (comparer.compare(convertedMaxBound, convertedValue) < 0) {
|
||||
maxBound = value;
|
||||
convertedMaxBound = convertedValue;
|
||||
}
|
||||
}
|
||||
|
||||
return { min: minBound, max: maxBound };
|
||||
return [minBound, maxBound];
|
||||
}
|
||||
|
||||
bounds(comparer?: Comparer<TElement>) {
|
||||
bounds(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#findBounds(undefined, comparer);
|
||||
}
|
||||
|
||||
boundsBy<TBy>(converter: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
boundsBy<TBy>(converter: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#findBounds(converter, comparer);
|
||||
}
|
||||
|
||||
order(comparer?: Comparer<TElement>): OrderedSequence<TElement> {
|
||||
order(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement> {
|
||||
return new OrderSequence<TElement>(this, false, comparer);
|
||||
}
|
||||
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement> {
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement> {
|
||||
return new OrderBySequence<TElement, TBy>(this, false, selector, comparer);
|
||||
}
|
||||
|
||||
orderDescending(comparer?: Comparer<TElement>): OrderedSequence<TElement> {
|
||||
orderDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement> {
|
||||
return new OrderSequence<TElement>(this, true, comparer);
|
||||
}
|
||||
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement> {
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement> {
|
||||
return new OrderBySequence<TElement, TBy>(this, true, selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: Equater<TElement>): Sequence<Sequence<TElement>> {
|
||||
partition(equater?: EqualityComparison<TElement>): Sequence<Sequence<TElement>> {
|
||||
return new PartitionSequence<TElement>(this, equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<Sequence<TElement>> {
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<Sequence<TElement>> {
|
||||
return new PartitionBySequence<TElement, TBy>(this, selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: Equater<TElement>): Sequence<TElement> {
|
||||
distinct(equater?: EqualityComparison<TElement>): Sequence<TElement> {
|
||||
return new DistinctSequence<TElement>(this, equater);
|
||||
}
|
||||
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement> {
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement> {
|
||||
return new DistinctBySequence<TElement, TBy>(this, selector, equater);
|
||||
}
|
||||
|
||||
union(sequence: Sequence<TElement>, equater?: Equater<TElement>): Sequence<TElement> {
|
||||
return new UnionSequence<TElement>(this, sequence, equater);
|
||||
union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement> {
|
||||
return new UnionSequence<TElement>(this, wrap(sequence), equater);
|
||||
}
|
||||
|
||||
unionBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement> {
|
||||
return new UnionBySequence<TElement, TBy>(this, sequence, selector, equater);
|
||||
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement> {
|
||||
return new UnionBySequence<TElement, TBy>(this, wrap(sequence), selector, equater);
|
||||
}
|
||||
|
||||
except(sequence: Sequence<TElement>): Sequence<TElement> {
|
||||
return new ExceptSequence<TElement>(this, sequence);
|
||||
except(sequence: Iterable<TElement>): Sequence<TElement> {
|
||||
return new ExceptSequence<TElement>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
exceptBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>): Sequence<TElement> {
|
||||
return new ExceptBySequence<TElement, TBy>(this, sequence, selector);
|
||||
exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>): Sequence<TElement> {
|
||||
return new ExceptBySequence<TElement, TBy>(this, wrap(sequence), selector);
|
||||
}
|
||||
|
||||
intersect(sequence: Sequence<TElement>): Sequence<TElement> {
|
||||
return new IntersectSequence<TElement>(this, sequence);
|
||||
intersect(sequence: Iterable<TElement>): Sequence<TElement> {
|
||||
return new IntersectSequence<TElement>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
intersectBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>): Sequence<TElement> {
|
||||
return new IntersectBySequence<TElement, TBy>(this, sequence, selector);
|
||||
intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>): Sequence<TElement> {
|
||||
return new IntersectBySequence<TElement, TBy>(this, wrap(sequence), selector);
|
||||
}
|
||||
|
||||
all(predicate: AnyPredicate<TElement>) {
|
||||
@@ -669,8 +670,8 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
}
|
||||
}
|
||||
|
||||
zip<TOther>(sequence: Sequence<TOther>): Sequence<[TElement, TOther]> {
|
||||
return new ZippedSequence<TElement, TOther>(this, sequence);
|
||||
zip<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]> {
|
||||
return new ZippedSequence<TElement, TOther>(this, wrap(sequence));
|
||||
}
|
||||
|
||||
indexed(): Sequence<[number, TElement]> {
|
||||
@@ -682,14 +683,19 @@ export abstract class BaseSequence<TElement> extends SequenceMarker implements S
|
||||
}
|
||||
|
||||
chunked(size: number): Sequence<Sequence<TElement>>;
|
||||
chunked(size: number, asArray: true): Sequence<TElement[]>;
|
||||
chunked<TResult>(size: number, transformer: SequencePipeline<TElement, TResult>): Sequence<TResult>;
|
||||
chunked<TResult>(size: number, transformer?: SequencePipeline<TElement, TResult>): Sequence<Sequence<TElement>> | Sequence<TResult> {
|
||||
chunked<TResult>(size: number, transformerOrAsArray?: true | SequencePipeline<TElement, TResult>): Sequence<Sequence<TElement>> | Sequence<TElement[]> | Sequence<TResult> {
|
||||
if (size <= 0) {
|
||||
throw new Error("Chunk size must be positive.");
|
||||
}
|
||||
|
||||
if (transformerOrAsArray === true) {
|
||||
return new ChunkedArraySequence<TElement>(this, size);
|
||||
}
|
||||
|
||||
const result = new ChunkedSequence<TElement>(this, size);
|
||||
return transformer ? result.select(transformer) : result;
|
||||
return transformerOrAsArray ? result.select(transformerOrAsArray) : result;
|
||||
}
|
||||
|
||||
random(options?: RandomOptions<TElement>) {
|
||||
@@ -814,39 +820,39 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
|
||||
return this.#sequence.select(selector);
|
||||
}
|
||||
|
||||
selectMany<TResult>(selector: Converter<TElement, Sequence<TResult>>) {
|
||||
selectMany<TResult>(selector: Converter<TElement, Iterable<TResult>>) {
|
||||
return this.#sequence.selectMany(selector);
|
||||
}
|
||||
|
||||
where<TFiltered extends TElement>(predicate: FilterPredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where(predicate: AnyPredicate<TElement>): Sequence<TElement>;
|
||||
where(predicate: any): Sequence<any> {
|
||||
return this.#sequence.where(predicate);
|
||||
}
|
||||
|
||||
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: Equater<TKey> | undefined): Sequence<GroupedSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: Equater<TKey> | undefined): Sequence<GroupedSequence<TKey, TResult>>;
|
||||
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TKey, TResult>>;
|
||||
groupBy(keySelector: any, elementSelector?: any, keyComparer?: any) {
|
||||
return this.#sequence.groupBy(keySelector, elementSelector, keyComparer);
|
||||
}
|
||||
|
||||
join<TOther, TKey>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: Equater<TKey> | undefined): Sequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: Equater<TKey> | undefined): Sequence<TResult>;
|
||||
join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<TResult>;
|
||||
join(sequence: any, firstKeySelector: any, secondKeySelector: any, resultSelector?: any, keyComparer?: any) {
|
||||
return this.#sequence.join(sequence, firstKeySelector, secondKeySelector, resultSelector, keyComparer);
|
||||
}
|
||||
|
||||
groupJoin<TOther, TKey>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: Equater<TKey> | undefined): Sequence<GroupedSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Sequence<TOther>, TResult>, keyComparer?: Equater<TKey> | undefined): Sequence<TResult>;
|
||||
groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<GroupedSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey> | undefined): Sequence<TResult>;
|
||||
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<TElement>) {
|
||||
contains(obj: TElement, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.contains(obj, equater);
|
||||
}
|
||||
|
||||
sequenceEquals(sequence: Sequence<TElement>, equater?: Equater<TElement>) {
|
||||
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.sequenceEquals(sequence, equater);
|
||||
}
|
||||
|
||||
@@ -858,11 +864,11 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
|
||||
return this.#sequence.prepend(obj);
|
||||
}
|
||||
|
||||
remove(obj: TElement, all?: boolean, equater?: Equater<TElement>) {
|
||||
remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.remove(obj, all, equater);
|
||||
}
|
||||
|
||||
concat(...sequences: Sequence<TElement>[]) {
|
||||
concat(...sequences: Iterable<TElement>[]) {
|
||||
return this.#sequence.concat(...sequences);
|
||||
}
|
||||
|
||||
@@ -902,83 +908,83 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
|
||||
return this.#sequence.aggregate(accumulator, seed, resultSelector);
|
||||
}
|
||||
|
||||
min(comparer?: Comparer<TElement>) {
|
||||
min(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#sequence.min(comparer);
|
||||
}
|
||||
|
||||
minBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
minBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#sequence.minBy(selector, comparer);
|
||||
}
|
||||
|
||||
max(comparer?: Comparer<TElement>) {
|
||||
max(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#sequence.max(comparer);
|
||||
}
|
||||
|
||||
maxBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
maxBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#sequence.maxBy(selector, comparer);
|
||||
}
|
||||
|
||||
bounds(comparer?: Comparer<TElement>) {
|
||||
bounds(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#sequence.bounds(comparer);
|
||||
}
|
||||
|
||||
boundsBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
boundsBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#sequence.boundsBy(selector, comparer);
|
||||
}
|
||||
|
||||
order(comparer?: Comparer<TElement>) {
|
||||
order(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#sequence.order(comparer);
|
||||
}
|
||||
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#sequence.orderBy(selector, comparer);
|
||||
}
|
||||
|
||||
orderDescending(comparer?: Comparer<TElement>) {
|
||||
orderDescending(comparer?: ComparisonOrComparer<TElement>) {
|
||||
return this.#sequence.orderDescending(comparer);
|
||||
}
|
||||
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>) {
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>) {
|
||||
return this.#sequence.orderByDescending(selector, comparer);
|
||||
}
|
||||
|
||||
partition(equater?: Equater<TElement> | undefined): Sequence<Sequence<TElement>> {
|
||||
partition(equater?: EqualityComparison<TElement> | undefined): Sequence<Sequence<TElement>> {
|
||||
return this.#sequence.partition(equater);
|
||||
}
|
||||
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy> | undefined): Sequence<Sequence<TElement>> {
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy> | undefined): Sequence<Sequence<TElement>> {
|
||||
return this.#sequence.partitionBy(selector, equater);
|
||||
}
|
||||
|
||||
distinct(equater?: Equater<TElement>) {
|
||||
distinct(equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.distinct(equater);
|
||||
}
|
||||
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>) {
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
|
||||
return this.#sequence.distinctBy(selector, equater);
|
||||
}
|
||||
|
||||
union(sequence: Sequence<TElement>, equater?: Equater<TElement>) {
|
||||
union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.union(sequence, equater);
|
||||
}
|
||||
|
||||
unionBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>) {
|
||||
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
|
||||
return this.#sequence.unionBy(sequence, selector, equater);
|
||||
}
|
||||
|
||||
except(sequence: Sequence<TElement>, equater?: Equater<TElement>) {
|
||||
except(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.except(sequence, equater);
|
||||
}
|
||||
|
||||
exceptBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>) {
|
||||
exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
|
||||
return this.#sequence.exceptBy(sequence, selector, equater);
|
||||
}
|
||||
|
||||
intersect(sequence: Sequence<TElement>, equater?: Equater<TElement>) {
|
||||
intersect(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>) {
|
||||
return this.#sequence.intersect(sequence, equater);
|
||||
}
|
||||
|
||||
intersectBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>) {
|
||||
intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>) {
|
||||
return this.#sequence.intersectBy(sequence, selector, equater);
|
||||
}
|
||||
|
||||
@@ -1030,7 +1036,7 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
|
||||
this.#sequence.forEach(action);
|
||||
}
|
||||
|
||||
zip<TOther>(sequence: Sequence<TOther>) {
|
||||
zip<TOther>(sequence: Iterable<TOther>) {
|
||||
return this.#sequence.zip(sequence);
|
||||
}
|
||||
|
||||
@@ -1043,9 +1049,10 @@ export class DelegatedSequence<TElement> extends SequenceMarker implements Seque
|
||||
}
|
||||
|
||||
chunked(size: number): Sequence<Sequence<TElement>>;
|
||||
chunked(size: number, asArray: true): Sequence<TElement[]>;
|
||||
chunked<TResult>(size: number, transformer: SequencePipeline<TElement, TResult>): Sequence<TResult>;
|
||||
chunked(size: number, transformer?: any): any {
|
||||
return this.#sequence.chunked(size, transformer);
|
||||
chunked(size: number, transformerOrAsArray?: any): any {
|
||||
return this.#sequence.chunked(size, transformerOrAsArray);
|
||||
}
|
||||
|
||||
random(options?: RandomOptions<TElement>) {
|
||||
@@ -1107,17 +1114,16 @@ export class GroupedSequenceImpl<TKey, TElement> extends DelegatedSequence<TElem
|
||||
}
|
||||
}
|
||||
|
||||
//# TODO
|
||||
export abstract class BaseOrderedSequence<TElement> extends BaseSequence<TElement> implements OrderedSequence<TElement> {
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #sorter: Comparer<TElement> | undefined;
|
||||
readonly #sorter: Comparer<TElement>;
|
||||
readonly #descending: boolean;
|
||||
|
||||
constructor(sequence: Sequence<TElement>, sorter: Comparer<TElement> | undefined, descending: boolean) {
|
||||
constructor(sequence: Sequence<TElement>, sorter: ComparisonOrComparer<TElement> | undefined, descending: boolean) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
this.#sorter = sorter;
|
||||
this.#sorter = sorter ? asComparer(sorter) : defaultComparer;
|
||||
this.#descending = descending;
|
||||
}
|
||||
|
||||
@@ -1141,19 +1147,19 @@ export abstract class BaseOrderedSequence<TElement> extends BaseSequence<TElemen
|
||||
return this.#descending;
|
||||
}
|
||||
|
||||
thenSelf(comparer?: Comparer<TElement>): OrderedSequence<TElement> {
|
||||
thenSelf(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement> {
|
||||
return new ThenOrderSequence(this, false, comparer);
|
||||
}
|
||||
|
||||
thenBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement> {
|
||||
thenBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement> {
|
||||
return new ThenOrderBySequence<TElement, TBy>(this, false, selector, comparer);
|
||||
}
|
||||
|
||||
thenSelfDescending(comparer?: Comparer<TElement>): OrderedSequence<TElement> {
|
||||
thenSelfDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement> {
|
||||
return new ThenOrderSequence(this, true, comparer);
|
||||
}
|
||||
|
||||
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement> {
|
||||
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement> {
|
||||
return new ThenOrderBySequence<TElement, TBy>(this, true, selector, comparer);
|
||||
}
|
||||
|
||||
@@ -1165,7 +1171,7 @@ export abstract class BaseOrderedSequence<TElement> extends BaseSequence<TElemen
|
||||
}
|
||||
|
||||
if (this.#sorter) {
|
||||
arr.sort(this.#descending ? reverseComparer(this.#sorter) : this.#sorter);
|
||||
arr.sort((this.#descending ? this.#sorter.reverse() : this.#sorter).comparison());
|
||||
} else {
|
||||
arr.sort();
|
||||
|
||||
@@ -1361,7 +1367,11 @@ export class WrappedArray<T> extends BaseSequence<T> {
|
||||
return this.#array.length;
|
||||
}
|
||||
|
||||
override contains(obj: T, equater?: Equater<T>): boolean {
|
||||
override _countWithoutPredicate() {
|
||||
return this.#array.length;
|
||||
}
|
||||
|
||||
override contains(obj: T, equater?: EqualityComparison<T>): boolean {
|
||||
if (equater) {
|
||||
return this.#array.some(x => equater(x, obj));
|
||||
}
|
||||
@@ -1457,7 +1467,7 @@ export class WrappedSet<T> extends BaseSequence<T> {
|
||||
return this.#set.size;
|
||||
}
|
||||
|
||||
override contains(obj: T, equater?: Equater<T>) {
|
||||
override contains(obj: T, equater?: EqualityComparison<T>) {
|
||||
if (equater) {
|
||||
return super.contains(obj, equater);
|
||||
}
|
||||
@@ -1487,7 +1497,7 @@ export class WrappedMap<K, V> extends BaseSequence<[K, V]> {
|
||||
return this.#map.size;
|
||||
}
|
||||
|
||||
override contains(obj: [K, V], equater?: Equater<[K, V]>) {
|
||||
override contains(obj: [K, V], equater?: EqualityComparison<[K, V]>) {
|
||||
if (equater) {
|
||||
return super.contains(obj, equater);
|
||||
}
|
||||
@@ -1596,9 +1606,9 @@ export class ConcatSequence<T> extends BaseSequence<T> {
|
||||
|
||||
class DistinctSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
readonly #equater: EqualityComparison<T> | undefined;
|
||||
|
||||
constructor(sequence: Sequence<T>, equater?: Equater<T>) {
|
||||
constructor(sequence: Sequence<T>, equater?: EqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1623,9 +1633,9 @@ class DistinctSequence<T> extends BaseSequence<T> {
|
||||
class DistinctBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #converter: Converter<T, U>;
|
||||
readonly #equater: Equater<U> | undefined;
|
||||
readonly #equater: EqualityComparison<U> | undefined;
|
||||
|
||||
constructor(sequence: Sequence<T>, converter: Converter<T, U>, equater?: Equater<U>) {
|
||||
constructor(sequence: Sequence<T>, converter: Converter<T, U>, equater?: EqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1650,9 +1660,9 @@ class DistinctBySequence<T, U> extends BaseSequence<T> {
|
||||
|
||||
class WhereSequence<TElement, TFiltered extends TElement> extends BaseSequence<TFiltered> {
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #predicate: FilterPredicate<TElement, TFiltered>;
|
||||
readonly #predicate: TypePredicate<TElement, TFiltered>;
|
||||
|
||||
constructor(sequence: Sequence<TElement>, predicate: FilterPredicate<TElement, TFiltered>) {
|
||||
constructor(sequence: Sequence<TElement>, predicate: TypePredicate<TElement, TFiltered>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1674,9 +1684,9 @@ class WhereSequence<TElement, TFiltered extends TElement> extends BaseSequence<T
|
||||
|
||||
class SelectManySequence<T, U> extends BaseSequence<U> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #converter: Converter<T, Sequence<U>>;
|
||||
readonly #converter: Converter<T, Iterable<U>>;
|
||||
|
||||
constructor(sequence: Sequence<T>, converter: Converter<T, Sequence<U>>) {
|
||||
constructor(sequence: Sequence<T>, converter: Converter<T, Iterable<U>>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -1758,7 +1768,7 @@ class SkipWhileSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
|
||||
override *iterator() {
|
||||
const e = asIterable(this.#sequence.iterator());
|
||||
const e = Iterator.from(this.#sequence);
|
||||
|
||||
for (const obj of e) {
|
||||
if (!this.#predicate(obj)) {
|
||||
@@ -1792,7 +1802,7 @@ class SkipLastSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
|
||||
override *iterator() {
|
||||
const iterator = this.#sequence.iterator();
|
||||
const iterator = Iterator.from(this.#sequence);
|
||||
const buffer = new Array<T>(this.#n); // n > 0
|
||||
let i = 0;
|
||||
|
||||
@@ -1808,7 +1818,7 @@ class SkipLastSequence<T> extends BaseSequence<T> {
|
||||
|
||||
i = 0;
|
||||
|
||||
for (const obj of asIterable(iterator)) {
|
||||
for (const obj of iterator) {
|
||||
yield buffer[i];
|
||||
buffer[i] = obj;
|
||||
i = (i + 1) % this.#n;
|
||||
@@ -1837,7 +1847,7 @@ class SkipSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
|
||||
override *iterator() {
|
||||
const iterator = this.#sequence.iterator();
|
||||
const iterator = Iterator.from(this.#sequence);
|
||||
let i = 0;
|
||||
|
||||
do {
|
||||
@@ -1848,7 +1858,7 @@ class SkipSequence<T> extends BaseSequence<T> {
|
||||
i++;
|
||||
} while (i < this.#n);
|
||||
|
||||
yield* asIterable(iterator);
|
||||
yield* iterator;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1947,45 +1957,26 @@ class TakeSequence<T> extends BaseSequence<T> {
|
||||
}
|
||||
|
||||
class OrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: Sequence<T>, descending: boolean, sorter?: Comparer<T>) {
|
||||
constructor(sequence: Sequence<T>, descending: boolean, sorter?: ComparisonOrComparer<T>) {
|
||||
super(sequence, sorter, descending);
|
||||
}
|
||||
}
|
||||
|
||||
class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
readonly #selector: Converter<T, U>;
|
||||
|
||||
constructor(sequence: Sequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
super(sequence, OrderBySequence.#createSorter(selector, sorter), descending);
|
||||
|
||||
this.#selector = selector;
|
||||
}
|
||||
|
||||
static #createSorter<T, U>(selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
const _sorter = sorter ?? defaultArrayComparer;
|
||||
return (a: T, b: T) => _sorter(selector(a), selector(b));
|
||||
constructor(sequence: Sequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: ComparisonOrComparer<U>) {
|
||||
super(sequence, createComparerUsing(selector, sorter), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: Comparer<T>) {
|
||||
super(sequence, combineComparers(sequence.comparer ?? defaultArrayComparer, sorter ?? defaultArrayComparer), descending);
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: ComparisonOrComparer<T>) {
|
||||
super(sequence, combineNullableComparers([sequence.comparer, sorter]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
readonly #selector: Converter<T, U>;
|
||||
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
super(sequence, ThenOrderBySequence.#createCombinedSorter(sequence.comparer, selector, sorter), descending);
|
||||
|
||||
this.#selector = selector;
|
||||
}
|
||||
|
||||
static #createCombinedSorter<T, U>(baseSorter: Comparer<T> | undefined, selector: Converter<T, U>, sorter?: Comparer<U>) {
|
||||
const _baseSorter = baseSorter ?? defaultArrayComparer;
|
||||
const _sorter = sorter ?? defaultArrayComparer;
|
||||
return combineComparers(_baseSorter, (a: T, b: T) => _sorter(selector(a), selector(b)));
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: ComparisonOrComparer<U>) {
|
||||
super(sequence, combineNullableComparers([sequence.comparer, createComparerUsing(selector, sorter)]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2110,9 +2101,9 @@ export class ZippedSequence<T, U> extends BaseSequence<[T, U]> {
|
||||
class UnionSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
readonly #equater: EqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: Equater<T>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2144,9 +2135,9 @@ class UnionBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
readonly #equater: Equater<U> | undefined;
|
||||
readonly #equater: EqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: Equater<U>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2178,9 +2169,9 @@ class UnionBySequence<T, U> extends BaseSequence<T> {
|
||||
class ExceptSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
readonly #equater: EqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: Equater<T>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2211,9 +2202,9 @@ class ExceptBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
readonly #equater: Equater<U> | undefined;
|
||||
readonly #equater: EqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: Equater<U>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2244,9 +2235,9 @@ class ExceptBySequence<T, U> extends BaseSequence<T> {
|
||||
class IntersectSequence<T> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #equater: Equater<T> | undefined;
|
||||
readonly #equater: EqualityComparison<T> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: Equater<T>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, equater?: EqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2261,9 +2252,7 @@ class IntersectSequence<T> extends BaseSequence<T> {
|
||||
override *iterator() {
|
||||
const set = createEqualitySet(this.#equater);
|
||||
|
||||
for (const obj of this.#second) {
|
||||
set.add(obj);
|
||||
}
|
||||
set.addAll(this.#second);
|
||||
|
||||
for (const obj of this.#first) {
|
||||
if (set.remove(obj)) {
|
||||
@@ -2277,9 +2266,9 @@ class IntersectBySequence<T, U> extends BaseSequence<T> {
|
||||
readonly #first: Sequence<T>;
|
||||
readonly #second: Sequence<T>;
|
||||
readonly #selector: Converter<T, U>;
|
||||
readonly #equater: Equater<U> | undefined;
|
||||
readonly #equater: EqualityComparison<U> | undefined;
|
||||
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: Equater<U>) {
|
||||
constructor(first: Sequence<T>, second: Sequence<T>, selector: Converter<T, U>, equater?: EqualityComparison<U>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2341,9 +2330,9 @@ class GroupBySequence<TElement, TKey, TResult> extends BaseSequence<GroupedSeque
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #keySelector: Converter<TElement, TKey>;
|
||||
readonly #elementSelector: Converter<TElement, TResult>;
|
||||
readonly #keyEquater: Equater<TKey> | undefined;
|
||||
readonly #keyEquater: EqualityComparison<TKey> | undefined;
|
||||
|
||||
constructor(sequence: Sequence<TElement>, keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyEquater?: Equater<TKey>) {
|
||||
constructor(sequence: Sequence<TElement>, keySelector: Converter<TElement, TKey>, elementSelector?: Converter<TElement, TResult>, keyEquater?: EqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2404,7 +2393,7 @@ class ChunkedSequence<T> extends BaseSequence<Sequence<T>> {
|
||||
for (const obj of this.#sequence) {
|
||||
chunk.push(obj);
|
||||
|
||||
if (chunk.length === this.#size) {
|
||||
if (chunk.length >= this.#size) {
|
||||
yield array(chunk);
|
||||
chunk = [];
|
||||
}
|
||||
@@ -2416,15 +2405,53 @@ class ChunkedSequence<T> extends BaseSequence<Sequence<T>> {
|
||||
}
|
||||
}
|
||||
|
||||
class ChunkedArraySequence<T> extends BaseSequence<T[]> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #size: number;
|
||||
|
||||
constructor(sequence: Sequence<T>, size: number) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
this.#size = size;
|
||||
}
|
||||
|
||||
override nonEnumeratedCount() {
|
||||
const n = this.#sequence.nonEnumeratedCount();
|
||||
return n < 0 ? super.nonEnumeratedCount() : Math.ceil(n / this.#size);
|
||||
}
|
||||
|
||||
override maxCount() {
|
||||
return Math.ceil(this.#sequence.maxCount() / this.#size);
|
||||
}
|
||||
|
||||
override *iterator() {
|
||||
let chunk: T[] = [];
|
||||
|
||||
for (const obj of this.#sequence) {
|
||||
chunk.push(obj);
|
||||
|
||||
if (chunk.length >= this.#size) {
|
||||
yield chunk;
|
||||
chunk = [];
|
||||
}
|
||||
}
|
||||
|
||||
if (chunk.length > 0) {
|
||||
yield chunk;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class JoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TResult> {
|
||||
readonly #first: Sequence<TOuter>;
|
||||
readonly #second: Sequence<TInner>;
|
||||
readonly #firstKeySelector: Converter<TOuter, TKey>;
|
||||
readonly #secondKeySelector: Converter<TInner, TKey>;
|
||||
readonly #resultSelector: BiConverter<TOuter, TInner, TResult>;
|
||||
readonly #keyEquater: Equater<TKey>;
|
||||
readonly #keyEquater: EqualityComparison<TKey>;
|
||||
|
||||
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, TInner, TResult>, keyEquater?: Equater<TKey>) {
|
||||
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, TInner, TResult>, keyEquater?: EqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2464,9 +2491,9 @@ class GroupJoinSequence<TOuter, TInner, TKey, TResult> extends BaseSequence<TRes
|
||||
readonly #firstKeySelector: Converter<TOuter, TKey>;
|
||||
readonly #secondKeySelector: Converter<TInner, TKey>;
|
||||
readonly #resultSelector: BiConverter<TOuter, Sequence<TInner>, TResult>;
|
||||
readonly #keyEquater: Equater<TKey>;
|
||||
readonly #keyEquater: EqualityComparison<TKey>;
|
||||
|
||||
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, Sequence<TInner>, TResult>, keyEquater?: Equater<TKey>) {
|
||||
constructor(first: Sequence<TOuter>, second: Sequence<TInner>, firstKeySelector: Converter<TOuter, TKey>, secondKeySelector: Converter<TInner, TKey>, resultSelector?: BiConverter<TOuter, Sequence<TInner>, TResult>, keyEquater?: EqualityComparison<TKey>) {
|
||||
super();
|
||||
|
||||
this.#first = first;
|
||||
@@ -2511,9 +2538,9 @@ class RemoveSequence<T> extends BaseSequence<T> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #obj: T;
|
||||
readonly #all: boolean;
|
||||
readonly #equater: Equater<T>;
|
||||
readonly #equater: EqualityComparison<T>;
|
||||
|
||||
constructor(sequence: Sequence<T>, obj: T, all?: boolean, equater?: Equater<T>) {
|
||||
constructor(sequence: Sequence<T>, obj: T, all?: boolean, equater?: EqualityComparison<T>) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2574,9 +2601,9 @@ class CacheSequence<T> extends BaseSequence<T> {
|
||||
|
||||
class PartitionSequence<T> extends BaseSequence<Sequence<T>> {
|
||||
readonly #sequence: Sequence<T>;
|
||||
readonly #equater: Equater<T>;
|
||||
readonly #equater: EqualityComparison<T>;
|
||||
|
||||
constructor(sequence: Sequence<T>, equater: Equater<T> | undefined) {
|
||||
constructor(sequence: Sequence<T>, equater: EqualityComparison<T> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
@@ -2605,9 +2632,9 @@ class PartitionSequence<T> extends BaseSequence<Sequence<T>> {
|
||||
class PartitionBySequence<TElement, TBy> extends BaseSequence<Sequence<TElement>> {
|
||||
readonly #sequence: Sequence<TElement>;
|
||||
readonly #selector: Converter<TElement, TBy>;
|
||||
readonly #equater: Equater<TBy>;
|
||||
readonly #equater: EqualityComparison<TBy>;
|
||||
|
||||
constructor(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater: Equater<TBy> | undefined) {
|
||||
constructor(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater: EqualityComparison<TBy> | undefined) {
|
||||
super();
|
||||
|
||||
this.#sequence = sequence;
|
||||
|
||||
@@ -74,6 +74,10 @@ export function keys(o: object): Sequence<string> {
|
||||
return array(Object.keys(o));
|
||||
}
|
||||
|
||||
export function values(o: object): Sequence<any> {
|
||||
return array(Object.values(o));
|
||||
}
|
||||
|
||||
export function func<T>(f: () => T): Sequence<T> {
|
||||
return new FunctionSequence(f);
|
||||
}
|
||||
@@ -138,8 +142,8 @@ export function randomSequence(random?: RandomGenerator): Sequence<number> {
|
||||
return new FunctionSequence(random ?? mathRandom);
|
||||
}
|
||||
|
||||
export function concat<T>(...sequences: Sequence<T>[]): Sequence<T> {
|
||||
return new ConcatSequence(sequences);
|
||||
export function concat<T>(...sequences: Iterable<T>[]): Sequence<T> {
|
||||
return new ConcatSequence(sequences.map(wrap));
|
||||
}
|
||||
|
||||
export function zip<T>(first: Sequence<T>, second: Sequence<T>): Sequence<[T, T]> {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { AsyncSequence } from "../async/types.js";
|
||||
import { Collector } from "../collector/types.js";
|
||||
import { ComparisonOrComparer, Comparer } from "../comparer/types.js";
|
||||
import { EqualityComparison } from "../equality-comparer/types.js";
|
||||
import { RandomOptions } from "../random/types.js";
|
||||
import { AnyPredicate, Converter, FilterPredicate, Equater, BiConverter, Accumulator, Comparer, Action } from "../types.js";
|
||||
import { AnyPredicate, Converter, TypePredicate, BiConverter, Accumulator, Action } from "../types.js";
|
||||
|
||||
export type SequencePipeline<TElement, TResult> = (sequence: Sequence<TElement>) => TResult;
|
||||
|
||||
@@ -18,31 +20,31 @@ export interface Sequence<TElement> extends Iterable<TElement> {
|
||||
maxCount(): number;
|
||||
|
||||
select<TResult>(selector: Converter<TElement, TResult>): Sequence<TResult>;
|
||||
selectMany<TResult>(selector: Converter<TElement, Sequence<TResult>>): Sequence<TResult>;
|
||||
selectMany<TResult>(selector: Converter<TElement, Iterable<TResult>>): Sequence<TResult>;
|
||||
|
||||
where<TFiltered extends TElement>(predicate: FilterPredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where<TFiltered extends TElement>(predicate: TypePredicate<TElement, TFiltered>): Sequence<TFiltered>;
|
||||
where(predicate: AnyPredicate<TElement>): Sequence<TElement>;
|
||||
|
||||
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: Equater<TKey>): Sequence<GroupedSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: Equater<TKey>): Sequence<GroupedSequence<TKey, TResult>>;
|
||||
groupBy<TKey>(keySelector: Converter<TElement, TKey>, elementSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TElement>>;
|
||||
groupBy<TKey, TResult>(keySelector: Converter<TElement, TKey>, elementSelector: Converter<TElement, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TKey, TResult>>;
|
||||
|
||||
join<TOther, TKey>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: Equater<TKey>): Sequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: Equater<TKey>): Sequence<TResult>;
|
||||
join<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<[TElement, TOther]>;
|
||||
join<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, TOther, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult>;
|
||||
|
||||
groupJoin<TOther, TKey>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: Equater<TKey>): Sequence<GroupedSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Sequence<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Sequence<TOther>, TResult>, keyComparer?: Equater<TKey>): Sequence<TResult>;
|
||||
groupJoin<TOther, TKey>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector?: undefined, keyComparer?: EqualityComparison<TKey>): Sequence<GroupedSequence<TElement, TOther>>;
|
||||
groupJoin<TOther, TKey, TResult>(sequence: Iterable<TOther>, firstKeySelector: Converter<TElement, TKey>, secondKeySelector: Converter<TOther, TKey>, resultSelector: BiConverter<TElement, Iterable<TOther>, TResult>, keyComparer?: EqualityComparison<TKey>): Sequence<TResult>;
|
||||
|
||||
contains(obj: TElement, equater?: Equater<TElement>): boolean;
|
||||
contains(obj: TElement, equater?: EqualityComparison<TElement>): boolean;
|
||||
|
||||
sequenceEquals(sequence: Sequence<TElement>, equater?: Equater<TElement>): boolean;
|
||||
sequenceEquals(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): boolean;
|
||||
|
||||
append(obj: TElement): Sequence<TElement>;
|
||||
|
||||
prepend(obj: TElement): Sequence<TElement>;
|
||||
|
||||
remove(obj: TElement, all?: boolean, equater?: Equater<TElement>): Sequence<TElement>;
|
||||
remove(obj: TElement, all?: boolean, equater?: EqualityComparison<TElement>): Sequence<TElement>;
|
||||
|
||||
concat(...sequences: Sequence<TElement>[]): Sequence<TElement>;
|
||||
concat(...sequences: Iterable<TElement>[]): Sequence<TElement>;
|
||||
|
||||
first(predicate?: AnyPredicate<TElement>): TElement;
|
||||
firstOrDefault(predicate?: AnyPredicate<TElement>, def?: TElement): TElement | undefined;
|
||||
@@ -60,35 +62,35 @@ export interface Sequence<TElement> extends Iterable<TElement> {
|
||||
aggregate<TAccumulator>(accumulator: Accumulator<TElement, TAccumulator>, seed?: TAccumulator): TAccumulator;
|
||||
aggregate<TAccumulator, TResult>(accumulator: Accumulator<TElement, TAccumulator>, seed?: TAccumulator, resultSelector?: Converter<TAccumulator, TResult>): TResult;
|
||||
|
||||
min(comparer?: Comparer<TElement>): TElement;
|
||||
minBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): TElement;
|
||||
min(comparer?: ComparisonOrComparer<TElement>): TElement;
|
||||
minBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): TElement;
|
||||
|
||||
max(comparer?: Comparer<TElement>): TElement;
|
||||
maxBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): TElement;
|
||||
max(comparer?: ComparisonOrComparer<TElement>): TElement;
|
||||
maxBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): TElement;
|
||||
|
||||
bounds(comparer?: Comparer<TElement>): { min: TElement, max: TElement; };
|
||||
boundsBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): { min: TElement, max: TElement; };
|
||||
bounds(comparer?: ComparisonOrComparer<TElement>): [min: TElement, max: TElement];
|
||||
boundsBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): [min: TElement, max: TElement];
|
||||
|
||||
order(comparer?: Comparer<TElement>): OrderedSequence<TElement>;
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement>;
|
||||
order(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>;
|
||||
orderBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>;
|
||||
|
||||
orderDescending(comparer?: Comparer<TElement>): OrderedSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement>;
|
||||
orderDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>;
|
||||
orderByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>;
|
||||
|
||||
partition(equater?: Equater<TElement>): Sequence<Sequence<TElement>>;
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<Sequence<TElement>>;
|
||||
partition(equater?: EqualityComparison<TElement>): Sequence<Sequence<TElement>>;
|
||||
partitionBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<Sequence<TElement>>;
|
||||
|
||||
distinct(equater?: Equater<TElement>): Sequence<TElement>;
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement>;
|
||||
distinct(equater?: EqualityComparison<TElement>): Sequence<TElement>;
|
||||
distinctBy<TBy>(selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
|
||||
|
||||
union(sequence: Sequence<TElement>, equater?: Equater<TElement>): Sequence<TElement>;
|
||||
unionBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement>;
|
||||
union(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
|
||||
unionBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
|
||||
|
||||
except(sequence: Sequence<TElement>, equater?: Equater<TElement>): Sequence<TElement>;
|
||||
exceptBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement>;
|
||||
except(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
|
||||
exceptBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
|
||||
|
||||
intersect(sequence: Sequence<TElement>, equater?: Equater<TElement>): Sequence<TElement>;
|
||||
intersectBy<TBy>(sequence: Sequence<TElement>, selector: Converter<TElement, TBy>, equater?: Equater<TBy>): Sequence<TElement>;
|
||||
intersect(sequence: Iterable<TElement>, equater?: EqualityComparison<TElement>): Sequence<TElement>;
|
||||
intersectBy<TBy>(sequence: Iterable<TElement>, selector: Converter<TElement, TBy>, equater?: EqualityComparison<TBy>): Sequence<TElement>;
|
||||
|
||||
all(predicate: AnyPredicate<TElement>): boolean;
|
||||
any(predicate: AnyPredicate<TElement>): boolean;
|
||||
@@ -108,13 +110,14 @@ export interface Sequence<TElement> extends Iterable<TElement> {
|
||||
|
||||
forEach(action: Action<TElement>): void;
|
||||
|
||||
zip<TOther>(sequence: Sequence<TOther>): Sequence<[TElement, TOther]>;
|
||||
zip<TOther>(sequence: Iterable<TOther>): Sequence<[TElement, TOther]>;
|
||||
|
||||
indexed(): Sequence<[number, TElement]>;
|
||||
|
||||
reversed(): Sequence<TElement>;
|
||||
|
||||
chunked(size: number): Sequence<Sequence<TElement>>;
|
||||
chunked(size: number, asArray: true): Sequence<TElement[]>;
|
||||
chunked<TResult>(size: number, transformer: SequencePipeline<TElement, TResult>): Sequence<TResult>;
|
||||
|
||||
random(options?: RandomOptions<TElement>): TElement | undefined;
|
||||
@@ -139,13 +142,13 @@ export interface GroupedSequence<TKey, TElement> extends Sequence<TElement> {
|
||||
}
|
||||
|
||||
export interface OrderedSequence<TElement> extends Sequence<TElement> {
|
||||
get comparer(): Comparer<TElement> | undefined;
|
||||
get comparer(): Comparer<TElement>;
|
||||
|
||||
thenSelf(comparer?: Comparer<TElement>): OrderedSequence<TElement>;
|
||||
thenSelf(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>;
|
||||
|
||||
thenBy<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement>;
|
||||
thenBy<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>;
|
||||
|
||||
thenSelfDescending(comparer?: Comparer<TElement>): OrderedSequence<TElement>;
|
||||
thenSelfDescending(comparer?: ComparisonOrComparer<TElement>): OrderedSequence<TElement>;
|
||||
|
||||
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: Comparer<TBy>): OrderedSequence<TElement>;
|
||||
thenByDescending<TBy>(selector: Converter<TElement, TBy>, comparer?: ComparisonOrComparer<TBy>): OrderedSequence<TElement>;
|
||||
}
|
||||
|
||||
15
src/types.ts
15
src/types.ts
@@ -1,15 +1,10 @@
|
||||
import { AsyncSequence } from "./async/types.js";
|
||||
import { Sequence } from "./sync/types.js";
|
||||
|
||||
export type Predicate<T> = (obj: T) => boolean;
|
||||
export type AnyPredicate<T> = (obj: T) => unknown;
|
||||
export type FilterPredicate<TElement, TFiltered extends TElement> = (obj: TElement) => obj is TFiltered;
|
||||
export type TypePredicate<TElement, TType extends TElement> = (obj: TElement) => obj is TType;
|
||||
export type Converter<TFrom, TTo> = (obj: TFrom) => TTo;
|
||||
export type BiConverter<TFromFirst, TFromSecond, TTo> = (first: TFromFirst, second: TFromSecond) => TTo;
|
||||
export type Action<T> = (obj: T) => unknown;
|
||||
export type Accumulator<TElement, TAccumulator> = (acc: TAccumulator, obj: TElement) => TAccumulator;
|
||||
export type Comparer<T> = (first: T, second: T) => number;
|
||||
export type Equater<T> = (first: T, second: T) => boolean;
|
||||
|
||||
export type MaybeAsyncIterable<T> = Iterable<T> | AsyncIterable<T>;
|
||||
export type MaybeAsyncIterator<T> = Iterator<T> | AsyncIterator<T>;
|
||||
@@ -18,12 +13,13 @@ export type AsyncFunction<TFunc extends (...args: any) => any> = TFunc extends (
|
||||
export type MaybePromise<T> = T | Promise<T>;
|
||||
export type MaybePromiseLike<T> = T | PromiseLike<T>;
|
||||
export type MaybeAsyncFunction<TFunc extends (...args: any) => any> = TFunc extends (...args: infer P) => infer R ? (...args: P) => MaybePromise<R> : never;
|
||||
export type MaybeAsyncSequence<T> = Sequence<T> | AsyncSequence<T>;
|
||||
|
||||
export type AsyncPredicate<T> = AsyncFunction<Predicate<T>>;
|
||||
export type AsyncAnyPredicate<T> = AsyncFunction<AnyPredicate<T>>;
|
||||
export type AsyncTypePredicate<TElement, TType extends TElement> = AsyncFunction<TypePredicate<TElement, TType>>;
|
||||
export type MaybeAsyncPredicate<T> = MaybeAsyncFunction<Predicate<T>>;
|
||||
export type MaybeAsyncAnyPredicate<T> = MaybeAsyncFunction<AnyPredicate<T>>;
|
||||
export type MaybeAsyncTypePredicate<TElement, TType extends TElement> = MaybeAsyncFunction<TypePredicate<TElement, TType>>;
|
||||
export type AsyncConverter<TFrom, TTo> = AsyncFunction<Converter<TFrom, TTo>>;
|
||||
export type MaybeAsyncConverter<TFrom, TTo> = MaybeAsyncFunction<Converter<TFrom, TTo>>;
|
||||
export type AsyncBiConverter<TFromFirst, TFromSecond, TTo> = AsyncFunction<BiConverter<TFromFirst, TFromSecond, TTo>>;
|
||||
@@ -32,7 +28,4 @@ export type AsyncAction<T> = AsyncFunction<Action<T>>;
|
||||
export type MaybeAsyncAction<T> = MaybeAsyncFunction<Action<T>>;
|
||||
export type AsyncAccumulator<TElement, TAccumulator> = AsyncFunction<Accumulator<TElement, TAccumulator>>;
|
||||
export type MaybeAsyncAccumulator<T, U> = MaybeAsyncFunction<Accumulator<T, U>>;
|
||||
export type AsyncComparer<T> = AsyncFunction<Comparer<T>>;
|
||||
export type MaybeAsyncComparer<T> = MaybeAsyncFunction<Comparer<T>>;
|
||||
export type AsyncEquater<T> = AsyncFunction<Equater<T>>;
|
||||
export type MaybeAsyncEquater<T> = MaybeAsyncFunction<Equater<T>>;
|
||||
|
||||
|
||||
86
src/utils.ts
86
src/utils.ts
@@ -1,95 +1,17 @@
|
||||
import { Comparer, MaybeAsyncComparer, AsyncComparer } from "./types.js";
|
||||
export type Nullable<T> = T | null | undefined;
|
||||
|
||||
export function isDefined<T = any>(obj: T): obj is NonNullable<T> {
|
||||
return obj !== undefined && obj !== null;
|
||||
}
|
||||
|
||||
export function isIterable<T = any>(obj: any): obj is Iterable<T> {
|
||||
return isDefined(obj) && typeof obj[Symbol.iterator] === "function";
|
||||
}
|
||||
|
||||
export function isAsyncIterable<T = any>(obj: any): obj is AsyncIterable<T> {
|
||||
return isDefined(obj) && typeof obj[Symbol.asyncIterator] === "function";
|
||||
}
|
||||
|
||||
export function identity<T>(obj: T) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
export function looseEquals<T>(a: T, b: T) {
|
||||
return a == b;
|
||||
}
|
||||
|
||||
export function strictEquals<T>(a: T, b: T) {
|
||||
return a === b;
|
||||
}
|
||||
|
||||
export function referenceEquals<T>(a: T, b: T) {
|
||||
return Object.is(a, b);
|
||||
}
|
||||
|
||||
export function numberCompare<T extends number | bigint>(a: T, b: T) {
|
||||
return a - b;
|
||||
}
|
||||
|
||||
export function operatorCompare(a: any, b: any) {
|
||||
return a < b ? -1 : a > b ? 1 : 0;
|
||||
}
|
||||
|
||||
export function defaultArrayComparer<T>(a: T, b: T) {
|
||||
if (a === undefined) {
|
||||
if (b === undefined) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (b === undefined) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
const aStr = `${a}`, bStr = `${b}`;
|
||||
|
||||
return aStr > bStr ? 1 : aStr < bStr ? -1 : 0;
|
||||
}
|
||||
|
||||
export function combineComparers<T>(first: Comparer<T>, second: Comparer<T>): Comparer<T> {
|
||||
return (a, b) => first(a, b) || second(a, b);
|
||||
}
|
||||
|
||||
export function combineAsyncComparers<T>(first: MaybeAsyncComparer<T>, second: MaybeAsyncComparer<T>): AsyncComparer<T> {
|
||||
return async (a, b) => await first(a, b) || await second(a, b);
|
||||
}
|
||||
|
||||
export function reverseComparer<T>(comparer: Comparer<T>): Comparer<T> {
|
||||
return (a, b) => comparer(b, a);
|
||||
}
|
||||
|
||||
export function reverseAsyncComparer<T>(comparer: MaybeAsyncComparer<T>): AsyncComparer<T> {
|
||||
return async (a, b) => await comparer(b, a);
|
||||
}
|
||||
|
||||
export function asArray<T>(iterable: Iterable<T>) {
|
||||
return Array.isArray(iterable) ? <T[]>iterable : Array.from(iterable);
|
||||
}
|
||||
|
||||
class WrappedIterator<T> implements Iterable<T> {
|
||||
readonly #iterator: Iterator<T>;
|
||||
|
||||
constructor(iterator: Iterator<T>) {
|
||||
this.#iterator = iterator;
|
||||
}
|
||||
|
||||
[Symbol.iterator]() {
|
||||
return this.#iterator;
|
||||
}
|
||||
}
|
||||
|
||||
export function asIterable<T>(iterator: Iterator<T>): Iterable<T> {
|
||||
return isIterable<T>(iterator) ? iterator : new WrappedIterator(iterator);
|
||||
}
|
||||
|
||||
class WrappedAsyncIterator<T> implements AsyncIterable<T> {
|
||||
readonly #iterator: AsyncIterator<T>;
|
||||
|
||||
@@ -115,14 +37,14 @@ const _emptyIterableIterator = new class EmptyIterableIterator implements Iterab
|
||||
return { done: true, value: undefined };
|
||||
}
|
||||
|
||||
return(value?: any): IteratorResult<any, any> {
|
||||
return(_value?: any): IteratorResult<any, any> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
throw(e?: any): IteratorResult<any, any> {
|
||||
throw(_e?: any): IteratorResult<any, any> {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export function emptyIterableIterator<T>(): IterableIterator<T> {
|
||||
return _emptyIterableIterator;
|
||||
|
||||
Reference in New Issue
Block a user