properly implement comparer and equality comparer combination
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { Collector } from "../collector/types.js";
|
||||
import { asAsyncComparer, combineNullableAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js";
|
||||
import { asAsyncComparer, combineAsyncComparers, createAsyncComparerUsing, defaultAsyncComparer } from "../comparer/async.js";
|
||||
import { MaybeAsyncComparisonOrComparer, AsyncComparer } from "../comparer/types.js";
|
||||
import { asAsyncEqualityComparer, defaultAsyncEqualityComparer } from "../equality-comparer/async.js";
|
||||
import { AsyncEqualityComparer, MaybeAsyncEqualityComparisonOrComparer } from "../equality-comparer/types.js";
|
||||
@@ -1713,13 +1713,13 @@ class OrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
|
||||
class ThenOrderAsyncSequence<T> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, sorter?: MaybeAsyncComparisonOrComparer<T>) {
|
||||
super(sequence, combineNullableAsyncComparers([sequence.comparer, sorter]), descending);
|
||||
super(sequence, combineAsyncComparers([sequence.comparer, sorter]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderByAsyncSequence<T, U> extends BaseOrderedAsyncSequence<T> {
|
||||
constructor(sequence: OrderedAsyncSequence<T>, descending: boolean, selector: MaybeAsyncConverter<T, U>, sorter?: MaybeAsyncComparisonOrComparer<U>) {
|
||||
super(sequence, combineNullableAsyncComparers([sequence.comparer, createAsyncComparerUsing(selector, sorter)]), descending);
|
||||
super(sequence, combineAsyncComparers([sequence.comparer, createAsyncComparerUsing(selector, sorter)]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ export function createAsyncComparerUsing<T, U>(projection: MaybeAsyncConverter<T
|
||||
return new MappedAsyncComparer(projection, comparison);
|
||||
}
|
||||
|
||||
export function combineNullableAsyncComparers<T>(comparers: Nullable<MaybeAsyncComparisonOrComparer<T>>[]): AsyncComparer<T> | undefined {
|
||||
let result = defaultAsyncComparer;
|
||||
export function combineAsyncComparers<T>(comparers: Iterable<Nullable<MaybeAsyncComparisonOrComparer<T>>>): AsyncComparer<T> | undefined {
|
||||
let result: AsyncComparer<T> = dummyAsyncComparer;
|
||||
|
||||
for (const comparer of comparers) {
|
||||
if (!comparer) {
|
||||
@@ -33,7 +33,7 @@ export function combineNullableAsyncComparers<T>(comparers: Nullable<MaybeAsyncC
|
||||
result = result.then(asAsyncComparer(comparer));
|
||||
}
|
||||
|
||||
return result === defaultAsyncComparer ? undefined : result;
|
||||
return result === dummyAsyncComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseAsyncComparer<T> implements AsyncComparer<T> {
|
||||
@@ -144,6 +144,24 @@ class ThenAsyncComparer<T> extends BaseAsyncComparer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
const dummyAsyncComparer = new class DummyAsyncComparer extends BaseAsyncComparer<any> {
|
||||
public override async compare(_a: any, _b: any): Promise<number> {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override then(comparer: AsyncComparer<any>): AsyncComparer<any> {
|
||||
return comparer;
|
||||
}
|
||||
|
||||
public override thenCompare(comparison: MaybeAsyncComparison<any>): AsyncComparer<any> {
|
||||
return createAsyncComparer(comparison);
|
||||
}
|
||||
|
||||
public override thenCompareUsing<U>(projection: MaybeAsyncConverter<any, U>, comparison?: MaybeAsyncComparisonOrComparer<U> | undefined): AsyncComparer<any> {
|
||||
return createAsyncComparerUsing(projection, comparison);
|
||||
}
|
||||
}
|
||||
|
||||
export const defaultAsyncComparer: AsyncComparer<any> = new class DefaultAsyncComparer extends BaseAsyncComparer<any> {
|
||||
public override async compare(a: any, b: any): Promise<number> {
|
||||
if (a === undefined) {
|
||||
|
||||
@@ -27,8 +27,8 @@ 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;
|
||||
export function combineComparers<T>(comparers: Iterable<Nullable<ComparisonOrComparer<T>>>) {
|
||||
let result: Comparer<T> = dummyComparer;
|
||||
|
||||
for (const comparer of comparers) {
|
||||
if (!comparer) {
|
||||
@@ -38,7 +38,7 @@ export function combineNullableComparers<T>(comparers: Nullable<ComparisonOrComp
|
||||
result = result.then(asComparer(comparer));
|
||||
}
|
||||
|
||||
return result === defaultComparer ? undefined : result;
|
||||
return result === dummyComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseComparer<T> implements Comparer<T> {
|
||||
@@ -75,6 +75,24 @@ export abstract class BaseComparer<T> implements Comparer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
const dummyComparer = new class DummyComparer extends BaseComparer<any> {
|
||||
public override compare(_a: any, _b: any): number {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public override then(comparer: Comparer<any>): Comparer<any> {
|
||||
return comparer;
|
||||
}
|
||||
|
||||
public override thenCompare(comparison: Comparison<any>): Comparer<any> {
|
||||
return createComparer(comparison);
|
||||
}
|
||||
|
||||
public override thenCompareUsing<U>(projection: Converter<any, U>, comparison?: ComparisonOrComparer<U> | undefined): Comparer<any> {
|
||||
return createComparerUsing(projection, comparison);
|
||||
}
|
||||
};
|
||||
|
||||
class SimpleComparer<T> extends BaseComparer<T> {
|
||||
readonly #comparison: Comparison<T>;
|
||||
|
||||
|
||||
@@ -22,8 +22,8 @@ export function createAsyncEqualityComparerUsing<T = any, U = any>(projection: M
|
||||
return new MappedAsyncEqualityComparer(projection, equalityComparison);
|
||||
}
|
||||
|
||||
export function combineNullableAsyncEqualityComparers<T>(equalityComparers: Nullable<MaybeAsyncEqualityComparisonOrComparer<T>>[]) {
|
||||
let result = defaultAsyncEqualityComparer;
|
||||
export function combineAsyncEqualityComparers<T>(equalityComparers: Iterable<Nullable<MaybeAsyncEqualityComparisonOrComparer<T>>>) {
|
||||
let result: AsyncEqualityComparer<T> = alwaysTrueAsyncEqualityComparer;
|
||||
|
||||
for (const equalityComparer of equalityComparers) {
|
||||
if (!equalityComparer) {
|
||||
@@ -33,7 +33,7 @@ export function combineNullableAsyncEqualityComparers<T>(equalityComparers: Null
|
||||
result = result.then(asAsyncEqualityComparer(equalityComparer));
|
||||
}
|
||||
|
||||
return result === defaultAsyncEqualityComparer ? undefined : result;
|
||||
return result === alwaysTrueAsyncEqualityComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseAsyncEqualityComparer<T> implements AsyncEqualityComparer<T> {
|
||||
@@ -140,6 +140,50 @@ class ThenAsyncEqualityComparer<T> extends BaseAsyncEqualityComparer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export const alwaysAsyncFalseEqualityComparer = new class AlwaysFalseAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
|
||||
public override async equals(_a: any, _b: any): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override opposite(): AsyncEqualityComparer<any> {
|
||||
return alwaysTrueAsyncEqualityComparer;
|
||||
}
|
||||
|
||||
public override then(_equalityComparer: AsyncEqualityComparer<any>): AsyncEqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public override thenEquals(_equalityComparison: MaybeAsyncEqualityComparison<any>): AsyncEqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public override thenEqualsUsing<U>(_projection: MaybeAsyncConverter<any, U>, _equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U> | undefined): AsyncEqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
export const alwaysTrueAsyncEqualityComparer = new class AlwaysTrueAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
|
||||
public override async equals(_a: any, _b: any): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override opposite(): AsyncEqualityComparer<any> {
|
||||
return alwaysAsyncFalseEqualityComparer;
|
||||
}
|
||||
|
||||
public override then(equalityComparer: AsyncEqualityComparer<any>): AsyncEqualityComparer<any> {
|
||||
return equalityComparer;
|
||||
}
|
||||
|
||||
public override thenEquals(equalityComparison: MaybeAsyncEqualityComparison<any>): AsyncEqualityComparer<any> {
|
||||
return createAsyncEqualityComparer(equalityComparison);
|
||||
}
|
||||
|
||||
public override thenEqualsUsing<U>(projection: MaybeAsyncConverter<any, U>, equalityComparison?: MaybeAsyncEqualityComparisonOrComparer<U> | undefined): AsyncEqualityComparer<any> {
|
||||
return createAsyncEqualityComparerUsing(projection, equalityComparison);
|
||||
}
|
||||
};
|
||||
|
||||
export const looseAsyncEqualityComparer: AsyncEqualityComparer<any> = new class LooseAsyncEqualityComparer extends BaseAsyncEqualityComparer<any> {
|
||||
public override async equals(a: any, b: any): Promise<boolean> {
|
||||
return a == b;
|
||||
|
||||
@@ -18,8 +18,8 @@ export function createEqualityComparerUsing<T = any, U = any>(projection: Conver
|
||||
return new MappedEqualityComparer(projection, equalityComparison);
|
||||
}
|
||||
|
||||
export function combineNullableEqualityComparers<T>(equalityComparers: Nullable<EqualityComparisonOrComparer<T>>[]) {
|
||||
let result = defaultEqualityComparer;
|
||||
export function combineEqualityComparers<T>(equalityComparers: Iterable<Nullable<EqualityComparisonOrComparer<T>>>) {
|
||||
let result: EqualityComparer<T> = alwaysTrueEqualityComparer;
|
||||
|
||||
for (const equalityComparer of equalityComparers) {
|
||||
if (!equalityComparer) {
|
||||
@@ -29,7 +29,7 @@ export function combineNullableEqualityComparers<T>(equalityComparers: Nullable<
|
||||
result = result.then(asEqualityComparer(equalityComparer));
|
||||
}
|
||||
|
||||
return result === defaultEqualityComparer ? undefined : result;
|
||||
return result === alwaysTrueEqualityComparer ? undefined : result;
|
||||
}
|
||||
|
||||
export abstract class BaseEqualityComparer<T> implements EqualityComparer<T> {
|
||||
@@ -126,6 +126,50 @@ class ThenEqualityComparer<T> extends BaseEqualityComparer<T> {
|
||||
}
|
||||
}
|
||||
|
||||
export const alwaysFalseEqualityComparer = new class AlwaysFalseEqualityComparer extends BaseEqualityComparer<any> {
|
||||
public override equals(_a: any, _b: any): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
public override opposite(): EqualityComparer<any> {
|
||||
return alwaysTrueEqualityComparer;
|
||||
}
|
||||
|
||||
public override then(_equalityComparer: EqualityComparer<any>): EqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public override thenEquals(_equalityComparison: EqualityComparison<any>): EqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public override thenEqualsUsing<U>(_projection: Converter<any, U>, _equalityComparison?: EqualityComparisonOrComparer<U> | undefined): EqualityComparer<any> {
|
||||
return this;
|
||||
}
|
||||
};
|
||||
|
||||
export const alwaysTrueEqualityComparer = new class AlwaysTrueEqualityComparer extends BaseEqualityComparer<any> {
|
||||
public override equals(_a: any, _b: any): boolean {
|
||||
return true;
|
||||
}
|
||||
|
||||
public override opposite(): EqualityComparer<any> {
|
||||
return alwaysFalseEqualityComparer;
|
||||
}
|
||||
|
||||
public override then(equalityComparer: EqualityComparer<any>): EqualityComparer<any> {
|
||||
return equalityComparer;
|
||||
}
|
||||
|
||||
public override thenEquals(equalityComparison: EqualityComparison<any>): EqualityComparer<any> {
|
||||
return createEqualityComparer(equalityComparison);
|
||||
}
|
||||
|
||||
public override thenEqualsUsing<U>(projection: Converter<any, U>, equalityComparison?: EqualityComparisonOrComparer<U> | undefined): EqualityComparer<any> {
|
||||
return createEqualityComparerUsing(projection, equalityComparison);
|
||||
}
|
||||
};
|
||||
|
||||
export const looseEqualityComparer: EqualityComparer<any> = new class LooseEqualityComparer extends BaseEqualityComparer<any> {
|
||||
public override equals(a: any, b: any): boolean {
|
||||
return a == b;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
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 { asComparer, combineComparers, createComparerUsing, defaultComparer } from "../comparer/sync.js";
|
||||
import { ComparisonOrComparer, Comparer } from "../comparer/types.js";
|
||||
import { asEqualityComparer, defaultEqualityComparer } from "../equality-comparer/sync.js";
|
||||
import { EqualityComparer, EqualityComparisonOrComparer } from "../equality-comparer/types.js";
|
||||
@@ -1974,13 +1974,13 @@ class OrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
|
||||
class ThenOrderSequence<T> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, sorter?: ComparisonOrComparer<T>) {
|
||||
super(sequence, combineNullableComparers([sequence.comparer, sorter]), descending);
|
||||
super(sequence, combineComparers([sequence.comparer, sorter]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
class ThenOrderBySequence<T, U> extends BaseOrderedSequence<T> {
|
||||
constructor(sequence: OrderedSequence<T>, descending: boolean, selector: Converter<T, U>, sorter?: ComparisonOrComparer<U>) {
|
||||
super(sequence, combineNullableComparers([sequence.comparer, createComparerUsing(selector, sorter)]), descending);
|
||||
super(sequence, combineComparers([sequence.comparer, createComparerUsing(selector, sorter)]), descending);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user