From 654151e06e6eeb6942315a4bda1b95ac63610d03 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Herv=C3=A9=20BECHER?= Date: Sat, 18 May 2024 15:07:08 +0200 Subject: [PATCH] refactor --- src/async/impl.ts | 32 ++++++++++------------ src/bitarray/impl.ts | 5 ++-- src/equality-map.ts | 4 +-- src/sync/impl.ts | 22 ++++++++------- src/utils.ts | 64 +++++++++++++++++++++++++++----------------- 5 files changed, 69 insertions(+), 58 deletions(-) diff --git a/src/async/impl.ts b/src/async/impl.ts index 303a0c0..0c132e2 100644 --- a/src/async/impl.ts +++ b/src/async/impl.ts @@ -7,7 +7,7 @@ import { AsyncRandomOptions } from "../random/types.js"; import { selectionSorter } from "../sorting.js"; import { Sequence } from "../sync/types.js"; import { MaybeAsyncConverter, MaybeAsyncPredicate, MaybeAsyncEquater, MaybeAsyncBiConverter, MaybeAsyncAccumulator, MaybeAsyncComparer, MaybeAsyncAction, MaybePromiseLike, MaybeAsyncGenerator, MaybeAsyncSequence } from "../types.js"; -import { strictEquals, identity, operatorCompare, asAsyncGenerator, defaultArrayComparer, combineAsyncComparers } from "../utils.js"; +import { strictEquals, identity, operatorCompare, defaultArrayComparer, combineAsyncComparers, asAsyncIterable } from "../utils.js"; import { array, empty, wrap } from "./index.js"; import { AsyncSequence, GroupedAsyncSequence, OrderedAsyncSequence } from "./types.js"; @@ -1467,7 +1467,7 @@ class SkipWhileAsyncSequence extends BaseAsyncSequence { break; } - yield* asAsyncGenerator(iterator); + yield* asAsyncIterable(iterator); } } @@ -1504,7 +1504,7 @@ class SkipLastAsyncSequence extends BaseAsyncSequence { i = 0; - for await (const obj of asAsyncGenerator(iterator)) { + for await (const obj of asAsyncIterable(iterator)) { yield buffer[i]; buffer[i] = obj; i = (i + 1) % this.#n; @@ -1540,7 +1540,7 @@ class SkipAsyncSequence extends BaseAsyncSequence { i++; } while (i < this.#n); - yield* asAsyncGenerator(iterator); + yield* asAsyncIterable(iterator); } } @@ -1705,23 +1705,17 @@ class PrependAsyncSequence extends BaseAsyncSequence { } } -class PeekAsyncSequence extends BaseAsyncSequence { - readonly #sequence: AsyncSequence; +class PeekAsyncSequence extends DelegatedAsyncSequence { readonly #action: MaybeAsyncAction; constructor(sequence: AsyncSequence, action: MaybeAsyncAction) { - super(); + super(sequence); - this.#sequence = sequence; this.#action = action; } - override async nonEnumeratedCount() { - return await this.#sequence.nonEnumeratedCount(); - } - override async *iterator() { - for await (const obj of this.#sequence) { + for await (const obj of this.sequence) { await this.#action(obj); yield obj; } @@ -1995,13 +1989,15 @@ class GroupByAsyncSequence extends BaseAsyncSequence { - return { - next: () => ({ done: true, value: undefined }) - }; + return emptyIterableIterator(); } get length() { diff --git a/src/equality-map.ts b/src/equality-map.ts index 4c962e0..9efc8bd 100644 --- a/src/equality-map.ts +++ b/src/equality-map.ts @@ -139,7 +139,7 @@ class CustomEqualityMap implements EqualityMap { *[Symbol.iterator]() { for (const entry of this.#list) { - yield [entry[0], entry[1]] as [K, V]; // no entry mutation allowed! + yield entry.slice() as [K, V]; // no entry mutation allowed! } } } @@ -287,7 +287,7 @@ class CustomAsyncEqualityMap implements AsyncEqualityMap { *[Symbol.iterator]() { for (const entry of this.#list) { - yield [entry[0], entry[1]] as [K, V]; // no entry mutation allowed! + yield entry.slice() as [K, V]; // no entry mutation allowed! } } } diff --git a/src/sync/impl.ts b/src/sync/impl.ts index 86b042f..e276c69 100644 --- a/src/sync/impl.ts +++ b/src/sync/impl.ts @@ -7,7 +7,7 @@ import { createQueue } from "../queue.js"; import { getRandomElement } from "../random/index.js"; import { RandomOptions } from "../random/types.js"; import { Converter, FilterPredicate, Equater, BiConverter, Predicate, Accumulator, Comparer, Action } from "../types.js"; -import { strictEquals, identity, operatorCompare, reverseComparer, wrapAsIterable, defaultArrayComparer, combineComparers } from "../utils.js"; +import { strictEquals, identity, operatorCompare, reverseComparer, asIterable, defaultArrayComparer, combineComparers } from "../utils.js"; import { array, empty } from "./index.js"; import { Sequence, GroupedSequence, OrderedSequence } from "./types.js"; @@ -1645,7 +1645,7 @@ class SkipWhileSequence extends BaseSequence { } override *iterator() { - const e = wrapAsIterable(this.#sequence.iterator()); + const e = asIterable(this.#sequence.iterator()); for (const obj of e) { if (!this.#predicate(obj)) { @@ -1695,7 +1695,7 @@ class SkipLastSequence extends BaseSequence { i = 0; - for (const obj of wrapAsIterable(iterator)) { + for (const obj of asIterable(iterator)) { yield buffer[i]; buffer[i] = obj; i = (i + 1) % this.#n; @@ -1735,7 +1735,7 @@ class SkipSequence extends BaseSequence { i++; } while (i < this.#n); - yield* wrapAsIterable(iterator); + yield* asIterable(iterator); } } @@ -1930,7 +1930,7 @@ class PeekSequence extends DelegatedSequence { } override *iterator() { - for (const obj of wrapAsIterable(super.iterator())) { + for (const obj of this.sequence) { this.#action(obj); yield obj; } @@ -2230,13 +2230,15 @@ class GroupBySequence extends BaseSequence(comparer: MaybeAsyncComparer): AsyncC return async (a, b) => await comparer(b, a); } -export function* asGenerator(iterator: Iterator) { - while (true) { - const next = iterator.next(); - - if (next.done) { - return next.value; - } - - yield next.value; - } -} - -export async function* asAsyncGenerator(iterator: MaybeAsyncIterator) { - while (true) { - const next = await iterator.next(); - - if (next.done) { - return next.value; - } - - yield next.value; - } -} - export function asArray(iterable: Iterable) { return Array.isArray(iterable) ? iterable : Array.from(iterable); } @@ -110,6 +86,44 @@ class WrappedIterator implements Iterable { } } -export function wrapAsIterable(iterator: Iterator): Iterable { +export function asIterable(iterator: Iterator): Iterable { return isIterable(iterator) ? iterator : new WrappedIterator(iterator); } + +class WrappedAsyncIterator implements AsyncIterable { + readonly #iterator: AsyncIterator; + + constructor(iterator: AsyncIterator) { + this.#iterator = iterator; + } + + [Symbol.asyncIterator]() { + return this.#iterator; + } +} + +export function asAsyncIterable(iterator: AsyncIterator): AsyncIterable { + return isAsyncIterable(iterator) ? iterator : new WrappedAsyncIterator(iterator); +} + +const _emptyIterableIterator = new class EmptyIterableIterator implements IterableIterator { + [Symbol.iterator]() { + return this; + } + + next(): IteratorResult { + return { done: true, value: undefined }; + } + + return(value?: any): IteratorResult { + throw new Error("Method not implemented."); + } + + throw(e?: any): IteratorResult { + throw new Error("Method not implemented."); + } +} + +export function emptyIterableIterator(): IterableIterator { + return _emptyIterableIterator; +}