diff --git a/README.md b/README.md index d996849..acdaf9d 100644 --- a/README.md +++ b/README.md @@ -123,6 +123,14 @@ Each of the following functions returns a push iterable instance: [reverseArray]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#reverseArray +### Iteration + +[`iterateIt(iterable, accept): PushIterator`][iterateIt] function iterates over the head elements of the given iterable +and returns its tail iterator. + +[iterateIt]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#iterateIt + + ### Iterable Consumption Each of the following functions accepts either [Iterable] or push iterable: @@ -136,9 +144,6 @@ Each of the following functions accepts either [Iterable] or push iterable: implemented by the provided function. - [`itsFind(iterable, search): R | undefined`][itsFind] - Searches for the value in `iterable`. - [`itsFirst(iterable): T | undefined`][itsFirst] - Extracts the first element of the given `iterable`, if any. -- [`itsHead(iterable, accept): PushIterator`][itsHead] - Iterates over the head elements of the given iterable and - returns its tail iterator. -- [`itsIterated(iterable, accept): boolean`][itsIterated] - Iterates over elements of the given `iterable`. - [`itsIterator(iterable)`][itsIterator] - Starts iteration over the given `iterable`. Always returns a push iterator. - [`itsMatch(iterable, test): T | undefined`][itsMatch] - Extracts the first element matching the given condition from `iterable`. @@ -153,8 +158,6 @@ Each of the following functions accepts either [Iterable] or push iterable: [itsEvery]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsEvery [itsFind]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsFind [itsFirst]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsFirst -[itsHead]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsHead -[itsIterated]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsIterated [itsIterator]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsIterator [itsMatch]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsMatch [itsReduction]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#itsReduction @@ -228,16 +231,11 @@ Each of the following functions accepts an indexed list of items, and returns a - [`isPushIterable(iterable)`][isPushIterable] - Checks whether the given iterable or iterator conforms to push iteration protocol. -- [`iteratorOf(iterable)`][iteratorOf] - Constructs iterator over elements of the given `iterable`. +- [`iteratorOf(iterable)`][iteratorOf] - Creates iterator over elements of the given `iterable`. - [`makePushIterable(iterate)`][makePushIterable] - Creates a push iterable implementation. - [`makePushIterator(forNext)`][makePushIterator] - Creates a push iterator implementation. -- [`pushHead(iterable, accept): PushIterator`][pushHead] - Iterates over the head elements of the given push iterable - and returns its tail iterator. -- [`pushIterated(iterable, accept): boolean`][pushIterated] - Iterates over elements of the given push iterable. [isPushIterable]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#isPushIterable [iteratorOf]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#iteratorOf [makePushIterable]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#makePushIterable [makePushIterator]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#makePushIterator -[pushHead]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#pushHead -[pushIterated]: https://proc7ts.github.io/push-iterator/modules/Module__proc7ts_push_iterator.html#pushIterated diff --git a/package.json b/package.json index f54e64d..2719f5f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@proc7ts/push-iterator", - "version": "2.6.0", + "version": "3.0.0-dev.0", "description": "Push iteration protocol", "keywords": [ "iteration", diff --git a/src/base/index.ts b/src/base/index.ts index ff8de5e..4b00e5e 100644 --- a/src/base/index.ts +++ b/src/base/index.ts @@ -2,5 +2,3 @@ export * from './is-push-iterable'; export * from './iterator-of'; export * from './make-push-iterable'; export * from './make-push-iterator'; -export * from './push-head'; -export * from './push-iterated'; diff --git a/src/consumption/its-head.spec.ts b/src/base/iterate-it.spec.ts similarity index 85% rename from src/consumption/its-head.spec.ts rename to src/base/iterate-it.spec.ts index fed18d1..ab57a04 100644 --- a/src/consumption/its-head.spec.ts +++ b/src/base/iterate-it.spec.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf } from '../base'; import { overMany } from '../construction'; -import { itsHead } from './its-head'; +import { iteratorOf } from './index'; +import { iterateIt } from './iterate-it'; describe('itsHead', () => { @@ -34,14 +34,14 @@ describe('itsHead', () => { it('iterates over all elements', () => { - const tail = itsHead(iterable, el => { result.push(el); }); + const tail = iterateIt(iterable, el => { result.push(el); }); expect(result).toEqual([1, 22, 333]); expect(tail.isOver()).toBe(true); }); it('iterates over head only', () => { - const tail = itsHead( + const tail = iterateIt( iterable, el => { result.push(el); @@ -54,7 +54,7 @@ describe('itsHead', () => { }); it('iterates over head and returns tail', () => { - const tail = itsHead( + const tail = iterateIt( iterable, el => { result.push(el); @@ -73,7 +73,7 @@ describe('itsHead', () => { describe('over empty array', () => { it('does not iterate', () => { - const tail = itsHead([], el => { result.push(el); }); + const tail = iterateIt([], el => { result.push(el); }); expect(result).toHaveLength(0); expect(tail.isOver()).toBe(true); diff --git a/src/consumption/its-head.ts b/src/base/iterate-it.ts similarity index 59% rename from src/consumption/its-head.ts rename to src/base/iterate-it.ts index c42bbc0..6250cb2 100644 --- a/src/consumption/its-head.ts +++ b/src/base/iterate-it.ts @@ -1,8 +1,9 @@ -import { isPushIterable, iteratorOf, pushHead } from '../base'; -import { iterateOverArray } from '../base/iterate-over-array.impl'; -import { PushIterator$empty } from '../base/push-iterator.empty.impl'; -import { rawIteratorPusher, toPushIterator } from '../base/raw-iterator.impl'; +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; +import { isPushIterable } from './index'; +import { iterateOverArray } from './iterate-over-array.impl'; +import { PushIterator$empty } from './push-iterator.empty.impl'; +import { rawIteratorPusher, toPushIterator } from './push-iterator.raw.impl'; /** * Iterates over elements of the given iterable. @@ -10,8 +11,6 @@ import type { PushIterator } from '../push-iterator'; * Calls `accept` method for each iterated element until there are elements to iterate, or `accept` returned either * `true` or `false`. * - * In contrast to {@link pushHead} function, this one accepts any iterable instance. - * * @typeParam T - Iterated elements type. * @param iterable - An iterable to iterate elements of. * @param accept - A function to push iterated elements to. Accepts iterated element as its only parameter. May return @@ -20,29 +19,30 @@ import type { PushIterator } from '../push-iterator'; * @returns A push iterator instance representing the tail of the given iterable. This iterator can be used to continue * iteration with, unless `accept` returned `false`. In the latter case the further iteration won't be possible. */ -export function itsHead(iterable: Iterable, accept: PushIterator.Acceptor): PushIterator { +export function iterateIt(iterable: Iterable, accept: PushIterator.Acceptor): PushIterator { if (isPushIterable(iterable)) { - return pushHead(iterable, accept); + return iterable[PushIterator__symbol](accept); } if (Array.isArray(iterable)) { - return arrayHead(iterable, accept); + return iterateIt$array(iterable, accept); } - return rawIterableHead(iterable, accept); + + return iterateIt$raw(iterable, accept); } -function arrayHead(array: ArrayLike, accept: PushIterator.Acceptor): PushIterator { +function iterateIt$array(array: ArrayLike, accept: PushIterator.Acceptor): PushIterator { return array.length ? iterateOverArray(array)(accept) : PushIterator$empty; } -function rawIterableHead( +function iterateIt$raw( iterable: Iterable, accept: PushIterator.Acceptor, ): PushIterator { - const it = iteratorOf(iterable); + const it = iterable[Symbol.iterator](); if (isPushIterable(it)) { - return pushHead(it, accept); + return it[PushIterator__symbol](accept); } const forEach = rawIteratorPusher(it); diff --git a/src/base/push-head.ts b/src/base/push-head.ts deleted file mode 100644 index 956c708..0000000 --- a/src/base/push-head.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PushIterable, PushIterator__symbol } from '../push-iterable'; -import type { PushIterator } from '../push-iterator'; - -/** - * Iterates over the head elements of the given push iterable. - * - * Calls `accept` method for each iterated element until there are elements to iterate, or `accept` returned either - * `true` or `false`. - * - * Calling this function is the same as calling `iterable[PushIterator__symbol](accept)`. - * - * @typeParam T - Iterated elements type. - * @param iterable - A push iterable to iterate elements of. - * @param accept - A function to push iterated elements to. Accepts iterated element as its only parameter. May return - * `true` to suspend iteration, or `false` to stop it. - * - * @returns A push iterator instance representing the tail of the given iterable. This iterator can be used to continue - * iteration with, unless `accept` returned `false`. In the latter case the further iteration won't be possible. - */ -export function pushHead(iterable: PushIterable, accept: PushIterator.Acceptor): PushIterator { - return iterable[PushIterator__symbol](accept); -} diff --git a/src/base/push-iterated.ts b/src/base/push-iterated.ts deleted file mode 100644 index e4c2352..0000000 --- a/src/base/push-iterated.ts +++ /dev/null @@ -1,22 +0,0 @@ -import { PushIterable, PushIterator__symbol } from '../push-iterable'; -import type { PushIterator } from '../push-iterator'; - -/** - * Iterates over elements of the given push iterable. - * - * Calls `accept` method for each iterated element until there are elements to iterate, or `accept` returned either - * `true` or `false`. - * - * Calling this function is the same as calling `!iterable[PushIterator__symbol](accept).isOver()`. - * - * @typeParam T - Iterated elements type. - * @param iterable - A push iterable to iterate elements of. - * @param accept - A function to push iterated elements to. Accepts iterated element as its only parameter. May return - * `true` to suspend iteration, or `false` to stop it. - * - * @returns `true` if there are more elements to iterate, or `false` otherwise. The former is possible only when - * iteration suspended, i.e. `accept` returned `true`. - */ -export function pushIterated(iterable: PushIterable, accept: PushIterator.Acceptor): boolean { - return !iterable[PushIterator__symbol](accept).isOver(); -} diff --git a/src/base/push-iterator.impl.ts b/src/base/push-iterator.impl.ts index 056704b..a085450 100644 --- a/src/base/push-iterator.impl.ts +++ b/src/base/push-iterator.impl.ts @@ -1,5 +1,5 @@ +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; -import { pushIterated } from './push-iterated'; export function PushIterator$iterator(this: T): T { return this; @@ -9,18 +9,15 @@ export function PushIterator$next(this: PushIterator): IteratorResult { for (; ;) { let result: IteratorYieldResult | undefined; - const over = !pushIterated( - this, - value => { - result = { value }; - return true; - }, - ); + const tail = this[PushIterator__symbol](value => { + result = { value }; + return true; + }); if (result) { return result; } - if (over) { + if (tail.isOver()) { return { done: true } as IteratorReturnResult; } } diff --git a/src/base/raw-iterator.impl.ts b/src/base/push-iterator.raw.impl.ts similarity index 100% rename from src/base/raw-iterator.impl.ts rename to src/base/push-iterator.raw.impl.ts diff --git a/src/construction/over-array.spec.ts b/src/construction/over-array.spec.ts index 6bae877..a913132 100644 --- a/src/construction/over-array.spec.ts +++ b/src/construction/over-array.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements, itsIterator } from '../consumption'; import { overArray } from './over-array'; @@ -17,21 +18,21 @@ describe('overArray', () => { expect([...overArray(array)]).toEqual(array); }); it('pushes array elements', () => { - expect(pushIterated(overArray(array), element => { + expect(iterateIt(overArray(array), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(array); }); it('resumes iteration', () => { const it = itsIterator(overArray(array)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(array.slice(1)); }); diff --git a/src/construction/over-elements-of.ts b/src/construction/over-elements-of.ts index dddc364..680e968 100644 --- a/src/construction/over-elements-of.ts +++ b/src/construction/over-elements-of.ts @@ -1,5 +1,5 @@ import { makePushIterable, makePushIterator } from '../base'; -import { itsHead } from '../consumption'; +import { iterateIt } from '../base/iterate-it'; import type { PushIterable } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; import { overIterable } from './over-iterable'; @@ -15,13 +15,13 @@ import { overNone } from './over-none'; */ export function overElementsOf(...sources: readonly Iterable[]): PushIterable { return sources.length > 1 - ? makePushIterable(iterateOverSubElements(sources)) + ? makePushIterable(overElementsOf$(sources)) : (sources.length ? overIterable(sources[0]) : overNone()); } -function iterateOverSubElements(sources: readonly Iterable[]): PushIterable.Iterate { +function overElementsOf$(sources: readonly Iterable[]): PushIterable.Iterate { return accept => { let i = 0; @@ -32,7 +32,7 @@ function iterateOverSubElements(sources: readonly Iterable[]): PushIterabl // eslint-disable-next-line @typescript-eslint/no-invalid-void-type let status: boolean | void; - const srcTail = itsHead(src, element => status = accept(element)); + const srcTail = iterateIt(src, element => status = accept(element)); if (srcTail.isOver()) { if (++i >= sources.length) { diff --git a/src/construction/over-indexed.spec.ts b/src/construction/over-indexed.spec.ts index 8b7e61c..c0736b1 100644 --- a/src/construction/over-indexed.spec.ts +++ b/src/construction/over-indexed.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements, itsIterator } from '../consumption'; import type { IndexedItemList } from './over-indexed'; import { overIndexed } from './over-indexed'; @@ -27,21 +28,21 @@ describe('overIndexed', () => { expect([...overIndexed(list)]).toEqual(array); }); it('pushes list items', () => { - expect(pushIterated(overIndexed(list), element => { + expect(iterateIt(overIndexed(list), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(array); }); it('resumes iteration', () => { const it = itsIterator(overIndexed(list)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(array.slice(1)); }); diff --git a/src/construction/over-iterable.spec.ts b/src/construction/over-iterable.spec.ts index 139b016..5cdb8e6 100644 --- a/src/construction/over-iterable.spec.ts +++ b/src/construction/over-iterable.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { PushIterator__symbol } from '../push-iterable'; import { overIterable } from './over-iterable'; import { overMany } from './over-many'; @@ -30,7 +31,7 @@ describe('overIterable', () => { const it = overIterable(new Set([1, 2, 3])); const result: number[] = []; - pushIterated(it, el => { result.push(el); }); + iterateIt(it, el => { result.push(el); }); expect(result).toEqual([1, 2, 3]); }); @@ -61,7 +62,7 @@ describe('overIterable', () => { const it = iteratorOf(overIterable(new Set())); - expect(pushIterated(it, () => true)).toBe(false); + expect(iterateIt(it, () => true).isOver()).toBe(true); expect(it.isOver()).toBe(true); }); }); diff --git a/src/construction/over-iterable.ts b/src/construction/over-iterable.ts index 86e2e7b..d1e3cc3 100644 --- a/src/construction/over-iterable.ts +++ b/src/construction/over-iterable.ts @@ -1,4 +1,3 @@ -import { iteratorOf } from '../base'; import type { PushIterable } from '../push-iterable'; import { overArray } from './over-array'; import { overIterator } from './over-iterator'; @@ -14,5 +13,5 @@ import { overIterator } from './over-iterator'; export function overIterable(iterable: Iterable): PushIterable { return Array.isArray(iterable) ? overArray(iterable) - : overIterator(() => iteratorOf(iterable)); + : overIterator(() => iterable[Symbol.iterator]()); } diff --git a/src/construction/over-iterator.ts b/src/construction/over-iterator.ts index 0dd0826..03706af 100644 --- a/src/construction/over-iterator.ts +++ b/src/construction/over-iterator.ts @@ -1,5 +1,5 @@ import { isPushIterable, makePushIterable } from '../base'; -import { rawIteratorPusher, toPushIterator } from '../base/raw-iterator.impl'; +import { rawIteratorPusher, toPushIterator } from '../base/push-iterator.raw.impl'; import type { PushIterable } from '../push-iterable'; import { PushIterator__symbol } from '../push-iterable'; import { overNone } from './over-none'; diff --git a/src/construction/over-none.spec.ts b/src/construction/over-none.spec.ts index bcdb5d2..d11b096 100644 --- a/src/construction/over-none.spec.ts +++ b/src/construction/over-none.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { PushIterator__symbol } from '../push-iterable'; import { overNone } from './over-none'; @@ -8,9 +9,9 @@ describe('overNone', () => { let iterated = false; - expect(pushIterated(overNone(), () => { + expect(iterateIt(overNone(), () => { iterated = true; - })).toBe(false); + }).isOver()).toBe(true); expect(iterated).toBe(false); }); it('does not iterate', () => { diff --git a/src/construction/over-one.spec.ts b/src/construction/over-one.spec.ts index ac49ef4..2c821b3 100644 --- a/src/construction/over-one.spec.ts +++ b/src/construction/over-one.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements } from '../consumption'; import { PushIterator__symbol } from '../push-iterable'; import { overOne } from './over-one'; @@ -10,13 +11,13 @@ describe('overOne', () => { const result: string[] = []; const it = overOne('one')[Symbol.iterator](); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect([...it]).toHaveLength(0); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['one']); }); diff --git a/src/construction/reverse-array.spec.ts b/src/construction/reverse-array.spec.ts index 63b9c8c..0013dbd 100644 --- a/src/construction/reverse-array.spec.ts +++ b/src/construction/reverse-array.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements } from '../consumption'; import { reverseArray } from './reverse-array'; @@ -16,15 +17,15 @@ describe('reverseArray', () => { }); it('iterates over array elements', () => { - expect(pushIterated(reverseArray(array), element => { + expect(iterateIt(reverseArray(array), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(reversed); }); it('pushes array elements', () => { - expect(pushIterated(reverseArray(array), element => { + expect(iterateIt(reverseArray(array), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(reversed); }); @@ -40,18 +41,18 @@ describe('reverseArray', () => { const it = iteratorOf(reverseArray(array)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(reversed.slice(1)); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(reversed.slice(1)); expect([...it]).toHaveLength(0); }); diff --git a/src/consumption/index.ts b/src/consumption/index.ts index 6dd27f2..f7f9059 100644 --- a/src/consumption/index.ts +++ b/src/consumption/index.ts @@ -4,8 +4,6 @@ export * from './its-empty'; export * from './its-every'; export * from './its-find'; export * from './its-first'; -export * from './its-head'; -export * from './its-iterated'; export * from './its-iterator'; export * from './its-match'; export * from './its-reduction'; diff --git a/src/consumption/its-each.ts b/src/consumption/its-each.ts index aeb396a..197b643 100644 --- a/src/consumption/its-each.ts +++ b/src/consumption/its-each.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Performs the given `action` for each element of the given `iterable`. @@ -9,5 +9,5 @@ import { itsIterated } from './its-iterated'; * parameter. */ export function itsEach(iterable: Iterable, action: (this: void, element: T) => void): void { - itsIterated(iterable, element => { action(element); }); + iterateIt(iterable, element => { action(element); }); } diff --git a/src/consumption/its-elements.ts b/src/consumption/its-elements.ts index fcd7f3b..2c98ffc 100644 --- a/src/consumption/its-elements.ts +++ b/src/consumption/its-elements.ts @@ -1,5 +1,6 @@ -import { isPushIterable, iteratorOf, pushIterated } from '../base'; +import { isPushIterable } from '../base'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; const itsElements$defaultConverter = (element: T): TConv => element as unknown as TConv; @@ -35,25 +36,29 @@ export function itsElements(source: Iterable, convert: (this: void, export function itsElements( source: Iterable, - convert: (this: void, element: T) => TConv = itsElements$defaultConverter, + convert?: (this: void, element: T) => TConv, ): TConv[] { if (isPushIterable(source)) { - return pushedElements(source, convert); + return itsElements$(source, convert); } - const it = iteratorOf(source); + const it = source[Symbol.iterator](); - return isPushIterable(it) ? pushedElements(it, convert) : Array.from(source, convert); + return isPushIterable(it) + ? itsElements$(it, convert) + : convert + ? Array.from(source, convert) + : [...source] as unknown[] as TConv[]; } -function pushedElements( +function itsElements$( it: PushIterable, - convert: (this: void, element: T) => TConv, + convert: (this: void, element: T) => TConv = itsElements$defaultConverter, ): TConv[] { const result: TConv[] = []; - pushIterated(it, element => { result.push(convert(element)); }); + it[PushIterator__symbol](element => { result.push(convert(element)); }); return result; } diff --git a/src/consumption/its-empty.ts b/src/consumption/its-empty.ts index 0cb5f3a..15108ad 100644 --- a/src/consumption/its-empty.ts +++ b/src/consumption/its-empty.ts @@ -1,5 +1,6 @@ -import { isPushIterable, iteratorOf, pushIterated } from '../base'; +import { isPushIterable } from '../base'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; /** * Checks whether the given `iterable` is empty. @@ -10,19 +11,21 @@ import type { PushIterable } from '../push-iterable'; */ export function itsEmpty(iterable: Iterable): boolean { if (isPushIterable(iterable)) { - return pushedEmpty(iterable); + return itsEmpty$(iterable); } - const it = iteratorOf(iterable); + const it = iterable[Symbol.iterator](); - return isPushIterable(it) ? pushedEmpty(it) : !!it.next().done; + return isPushIterable(it) + ? itsEmpty$(it) + : !!it.next().done; } -function pushedEmpty(it: PushIterable): boolean { +function itsEmpty$(it: PushIterable): boolean { let isEmpty = true; - pushIterated(it, _element /* Unused parameter to prevent deoptimization */ => isEmpty = false); + it[PushIterator__symbol](_element /* Unused parameter to prevent deoptimization */ => isEmpty = false); return isEmpty; } diff --git a/src/consumption/its-every.ts b/src/consumption/its-every.ts index 6556f19..e84e274 100644 --- a/src/consumption/its-every.ts +++ b/src/consumption/its-every.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Tests whether all elements of the given `iterable` pass the test implemented by the provided function. @@ -18,7 +18,7 @@ export function itsEvery( let allMatch = true; - itsIterated( + iterateIt( iterable, (element: T): boolean | void => { allMatch = !!test(element); diff --git a/src/consumption/its-find.ts b/src/consumption/its-find.ts index 07f968f..22960f8 100644 --- a/src/consumption/its-find.ts +++ b/src/consumption/its-find.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Searches for the value in `iterable`. @@ -19,7 +19,7 @@ export function itsFind( let find: TFound | undefined; - itsIterated( + iterateIt( iterable, (element: T): boolean | void => { diff --git a/src/consumption/its-first.ts b/src/consumption/its-first.ts index 7a4a6ac..12134a3 100644 --- a/src/consumption/its-first.ts +++ b/src/consumption/its-first.ts @@ -1,5 +1,6 @@ -import { isPushIterable, iteratorOf, pushIterated } from '../base'; +import { isPushIterable } from '../base'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; /** * Extracts the first element of the given `iterable`, if any. @@ -11,30 +12,27 @@ import type { PushIterable } from '../push-iterable'; */ export function itsFirst(iterable: Iterable): T | undefined { if (isPushIterable(iterable)) { - return pushedFirst(iterable); + return itsFirst$(iterable); } - const it = iteratorOf(iterable); + const it = iterable[Symbol.iterator](); - return isPushIterable(it) ? pushedFirst(it) : rawFirst(it); + return isPushIterable(it) ? itsFirst$(it) : itsFirst$raw(it); } -function pushedFirst(it: PushIterable): T | undefined { +function itsFirst$(it: PushIterable): T | undefined { let first: T | undefined; - pushIterated( - it, - element => { - first = element; - return false; - }, - ); + it[PushIterator__symbol](element => { + first = element; + return false; + }); return first; } -function rawFirst(it: Iterator): T | undefined { +function itsFirst$raw(it: Iterator): T | undefined { const result = it.next(); diff --git a/src/consumption/its-iterated.spec.ts b/src/consumption/its-iterated.spec.ts deleted file mode 100644 index 2429ae5..0000000 --- a/src/consumption/its-iterated.spec.ts +++ /dev/null @@ -1,96 +0,0 @@ -import { beforeEach, describe, expect, it } from '@jest/globals'; -import { overMany } from '../construction'; -import { itsIterated } from './its-iterated'; -import { itsIterator } from './its-iterator'; - -describe('itsIterated', () => { - describe('over raw iterable', () => { - it('pushes elements', () => { - - const result: number[] = []; - - itsIterated([1, 2, 3], el => { - result.push(el); - }); - - expect(result).toEqual([1, 2, 3]); - }); - it('stops when `false` returned', () => { - - const result: number[] = []; - - itsIterated([1, 2, 3], el => { - result.push(el); - if (el > 1) { - return false; - } - return; - }); - - expect(result).toEqual([1, 2]); - }); - }); - - describe('over push iterable', () => { - it('pushes elements', () => { - - const result: number[] = []; - - itsIterated(overMany(1, 2, 3), el => { - result.push(el); - }); - - expect(result).toEqual([1, 2, 3]); - }); - it('stops when `false` returned', () => { - - const result: number[] = []; - - itsIterated(overMany(1, 2, 3), el => { - result.push(el); - if (el > 1) { - return false; - } - return; - }); - - expect(result).toEqual([1, 2]); - }); - }); - - describe('over iterable with push iterator', () => { - - let iterable: Iterable; - - beforeEach(() => { - iterable = { - [Symbol.iterator]: () => itsIterator([1, 2, 3]), - }; - }); - - it('pushes elements', () => { - - const result: number[] = []; - - itsIterated(iterable, el => { - result.push(el); - }); - - expect(result).toEqual([1, 2, 3]); - }); - it('stops when `false` returned', () => { - - const result: number[] = []; - - itsIterated(iterable, el => { - result.push(el); - if (el > 1) { - return false; - } - return; - }); - - expect(result).toEqual([1, 2]); - }); - }); -}); diff --git a/src/consumption/its-iterated.ts b/src/consumption/its-iterated.ts deleted file mode 100644 index 78d0334..0000000 --- a/src/consumption/its-iterated.ts +++ /dev/null @@ -1,45 +0,0 @@ -import { isPushIterable, iteratorOf, pushIterated } from '../base'; -import type { PushIterator } from '../push-iterator'; - -/** - * Iterates over elements of the given iterable. - * - * Calls `accept` method for each iterated element until there are elements to iterate, or `accept` returned either - * `true` or `false`. - * - * In contrast to {@link pushIterated} function, this one accepts any iterable instance. - * - * @typeParam T - Iterated elements type. - * @param iterable - An iterable to iterate elements of. - * @param accept - A function to push iterated elements to. Accepts iterated element as its only parameter. May return - * `true` to suspend iteration, or `false` to stop it. - * - * @returns `true` if there are more elements to iterate, or `false` otherwise. The former is possible only when - * iteration suspended, i.e. `accept` returned `true`. - */ -export function itsIterated(iterable: Iterable, accept: PushIterator.Acceptor): boolean { - if (isPushIterable(iterable)) { - return pushIterated(iterable, accept); - } - - const it = iteratorOf(iterable); - - if (isPushIterable(it)) { - return pushIterated(it, accept); - } - - for (; ;) { - - const next = it.next(); - - if (next.done) { - return false; - } - - const status = accept(next.value); - - if (typeof status === 'boolean') { - return status; - } - } -} diff --git a/src/consumption/its-iterator.spec.ts b/src/consumption/its-iterator.spec.ts index 696c51b..13e3759 100644 --- a/src/consumption/its-iterator.spec.ts +++ b/src/consumption/its-iterator.spec.ts @@ -1,7 +1,7 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { makePushIterator, pushIterated } from '../base'; +import { makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { overMany } from '../construction'; -import { itsIterated } from './its-iterated'; import { itsIterator } from './its-iterator'; describe('itsIterator', () => { @@ -30,9 +30,9 @@ describe('itsIterator', () => { const result: number[] = []; - expect(itsIterated(generate(), element => { + expect(iterateIt(generate(), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([1, 2, 3]); }); it('ignores generator return', () => { @@ -45,9 +45,9 @@ describe('itsIterator', () => { const result: number[] = []; - expect(itsIterated(generate(), element => { + expect(iterateIt(generate(), element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([1, 2]); }); @@ -56,9 +56,9 @@ describe('itsIterator', () => { const it = itsIterator(iterable); const result: typeof array = []; - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(array); }); @@ -67,10 +67,10 @@ describe('itsIterator', () => { const it = itsIterator(iterable); const result: typeof array = []; - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); return false; - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(array.slice(0, 1)); }); @@ -79,12 +79,12 @@ describe('itsIterator', () => { const it = itsIterator(iterable); const result: typeof array = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(array.slice(1)); }); @@ -93,11 +93,11 @@ describe('itsIterator', () => { const it = itsIterator(iterable); const result: typeof array = []; - expect(pushIterated(it, () => {/* noop */})).toBe(false); + expect(iterateIt(it, () => void 0).isOver()).toBe(true); expect(it.isOver()).toBe(true); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toHaveLength(0); }); @@ -108,7 +108,7 @@ describe('itsIterator', () => { const it = itsIterator(iterable); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); expect([...it]).toEqual(array.slice(1)); diff --git a/src/consumption/its-iterator.ts b/src/consumption/its-iterator.ts index c97d7c8..ddefbd5 100644 --- a/src/consumption/its-iterator.ts +++ b/src/consumption/its-iterator.ts @@ -1,5 +1,5 @@ -import { isPushIterable, iteratorOf } from '../base'; -import { rawIteratorPusher, toPushIterator } from '../base/raw-iterator.impl'; +import { isPushIterable } from '../base'; +import { rawIteratorPusher, toPushIterator } from '../base/push-iterator.raw.impl'; import type { PushIterator } from '../push-iterator'; /** @@ -12,7 +12,9 @@ import type { PushIterator } from '../push-iterator'; */ export function itsIterator(iterable: Iterable): PushIterator { - const it = iteratorOf(iterable); + const it = iterable[Symbol.iterator](); - return isPushIterable(it) ? it : toPushIterator(it, rawIteratorPusher(it)); + return isPushIterable(it) + ? it + : toPushIterator(it, rawIteratorPusher(it)); } diff --git a/src/consumption/its-match.ts b/src/consumption/its-match.ts index 0fdb697..b2e5fca 100644 --- a/src/consumption/its-match.ts +++ b/src/consumption/its-match.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Extracts the first element matching the given condition from `iterable`. @@ -14,7 +14,7 @@ export function itsMatch(iterable: Iterable, test: (this: void, element: T let match: T | undefined; - itsIterated( + iterateIt( iterable, (element: T): boolean | void => { if (test(element)) { diff --git a/src/consumption/its-reduction.ts b/src/consumption/its-reduction.ts index 0ef1315..50927db 100644 --- a/src/consumption/its-reduction.ts +++ b/src/consumption/its-reduction.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Applies a function against an accumulator and each element of the given `iterable` to reduce elements to a single @@ -21,7 +21,7 @@ export function itsReduction( let reduced = initialValue; - itsIterated(iterable, element => { reduced = reducer(reduced, element); }); + iterateIt(iterable, element => { reduced = reducer(reduced, element); }); return reduced; } diff --git a/src/consumption/its-some.ts b/src/consumption/its-some.ts index 787f61c..5b019a6 100644 --- a/src/consumption/its-some.ts +++ b/src/consumption/its-some.ts @@ -1,4 +1,4 @@ -import { itsIterated } from './its-iterated'; +import { iterateIt } from '../base/iterate-it'; /** * Tests whether at least one element of the given `iterable` passes the test implemented by the provided function. @@ -18,7 +18,7 @@ export function itsSome( let someMatches = false; - itsIterated( + iterateIt( iterable, (element: T): boolean | void => { someMatches = !!test(element); diff --git a/src/transformation/filter-array.spec.ts b/src/transformation/filter-array.spec.ts index 228419f..9e8761a 100644 --- a/src/transformation/filter-array.spec.ts +++ b/src/transformation/filter-array.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { pushIterated } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements, itsIterator } from '../consumption'; import { filterArray } from './filter-array'; @@ -16,7 +16,7 @@ describe('filterArray', () => { const it = itsIterator(filterArray([11, 22, 33], element => element > 11)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); expect([...it]).toEqual([33]); @@ -29,18 +29,18 @@ describe('filterArray', () => { const it = itsIterator(filterArray([11, 22, 33], element => element > 11)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([33]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([33]); }); }); diff --git a/src/transformation/filter-indexed.spec.ts b/src/transformation/filter-indexed.spec.ts index f6a9b1c..0a6fe1e 100644 --- a/src/transformation/filter-indexed.spec.ts +++ b/src/transformation/filter-indexed.spec.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { pushIterated } from '../base'; +import { iterateIt } from '../base/iterate-it'; import type { IndexedItemList } from '../construction'; import { itsElements, itsIterator } from '../consumption'; import { filterIndexed } from './filter-indexed'; @@ -32,7 +32,7 @@ describe('filterIndexed', () => { const it = itsIterator(filterIndexed(list, element => element > 11)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); expect([...it]).toEqual([33]); @@ -45,18 +45,18 @@ describe('filterIndexed', () => { const it = itsIterator(filterIndexed(list, element => element > 11)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([33]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([33]); }); }); diff --git a/src/transformation/filter-it.spec.ts b/src/transformation/filter-it.spec.ts index 0fbdb08..8ca986e 100644 --- a/src/transformation/filter-it.spec.ts +++ b/src/transformation/filter-it.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, makePushIterator, pushIterated } from '../base'; +import { iteratorOf, makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { overMany, overNone } from '../construction'; import { itsElements } from '../consumption'; import type { PushIterable } from '../push-iterable'; @@ -22,7 +23,7 @@ describe('filterIt', () => { const it = iteratorOf(filterIt(new Set([11, 22, 33]), element => element > 11)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect([...it]).toEqual([33]); expect([...it]).toHaveLength(0); @@ -32,18 +33,18 @@ describe('filterIt', () => { const it = iteratorOf(filterIt(new Set([11, 22, 33]), element => element > 11)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([33]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([33]); }); @@ -65,7 +66,7 @@ describe('filterIt', () => { const it = iteratorOf(filterIt(new Set(), element => element > 11)); - expect(pushIterated(it, () => true)).toBe(false); + expect(iterateIt(it, () => true).isOver()).toBe(true); expect(it.isOver()).toBe(true); }); }); @@ -109,7 +110,7 @@ describe('filterIt', () => { const it = iteratorOf(filterIt(overMany(11, 22, 33), element => element > 11)); - pushIterated(it, () => true); + iterateIt(it, () => true); expect(it.isOver()).toBe(false); expect([...it]).toEqual([33]); @@ -144,7 +145,7 @@ describe('filterIt', () => { const it = iteratorOf(iterable); - pushIterated(it, () => true); + iterateIt(it, () => true); expect(it.isOver()).toBe(false); expect([...it]).toEqual([33]); diff --git a/src/transformation/filter-it.ts b/src/transformation/filter-it.ts index f278f25..af392b0 100644 --- a/src/transformation/filter-it.ts +++ b/src/transformation/filter-it.ts @@ -1,6 +1,7 @@ -import { isPushIterable, iteratorOf, makePushIterable, makePushIterator, pushHead } from '../base'; +import { isPushIterable, makePushIterable, makePushIterator } from '../base'; import { overNone } from '../construction'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; /** @@ -43,27 +44,21 @@ export function filterIt( ): PushIterable { return makePushIterable(accept => { - const forNext = isPushIterable(source) ? filterPusher(source, test) : filterRawPusher(source, test); + const forNext = isPushIterable(source) + ? filterIt$(source, test) + : filterIt$raw(source, test); return accept && !forNext(accept) ? overNone() : makePushIterator(forNext); }); } -function filterPusher( +function filterIt$( source: PushIterable, test: (this: void, element: T) => boolean, ): PushIterator.Pusher { return accept => { - const tail = pushHead( - source, - element => { - if (test(element)) { - return accept(element); - } - return; - }, - ); + const tail = source[PushIterator__symbol](element => test(element) ? accept(element) : void 0); source = tail; @@ -71,15 +66,15 @@ function filterPusher( }; } -function filterRawPusher( +function filterIt$raw( source: Iterable, test: (this: void, element: T) => boolean, ): PushIterator.Pusher { - const it = iteratorOf(source); + const it = source[Symbol.iterator](); if (isPushIterable(it)) { - return filterPusher(it, test); + return filterIt$(it, test); } return accept => { diff --git a/src/transformation/flat-map-it.ts b/src/transformation/flat-map-it.ts index 0a5e57d..b496c05 100644 --- a/src/transformation/flat-map-it.ts +++ b/src/transformation/flat-map-it.ts @@ -1,7 +1,8 @@ -import { isPushIterable, iteratorOf, makePushIterable, makePushIterator, pushHead } from '../base'; +import { isPushIterable, makePushIterable, makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { overNone } from '../construction'; -import { itsHead } from '../consumption'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; /** @@ -38,13 +39,15 @@ export function flatMapIt( ): PushIterable { return makePushIterable(accept => { - const forNext = isPushIterable(source) ? flatMapPusher(source, convert) : flatMapRawPusher(source, convert); + const forNext = isPushIterable(source) + ? flatMap$(source, convert) + : flatMap$raw(source, convert); return accept && !forNext(accept) ? overNone() : makePushIterator(forNext); }); } -function flatMapPusher( +function flatMap$( source: PushIterable, convert: (this: void, element: TSrc) => Iterable, ): PushIterator.Pusher { @@ -56,7 +59,7 @@ function flatMapPusher( for (; ;) { while (!subs) { - const sourceTail = pushHead(source, src => { + const sourceTail = source[PushIterator__symbol](src => { subs = convert(src); return true; }); @@ -71,9 +74,8 @@ function flatMapPusher( } } - // eslint-disable-next-line @typescript-eslint/no-invalid-void-type let status: boolean | void; - const subsTail: PushIterator = itsHead(subs, element => status = accept(element)); + const subsTail: PushIterator = iterateIt(subs, element => status = accept(element)); if (subsTail.isOver()) { subs = undefined; @@ -91,15 +93,15 @@ function flatMapPusher( }; } -function flatMapRawPusher( +function flatMap$raw( source: Iterable, convert: (this: void, element: TSrc) => Iterable, ): PushIterator.Pusher { - const it = iteratorOf(source); + const it = source[Symbol.iterator](); if (isPushIterable(it)) { - return flatMapPusher(it, convert); + return flatMap$(it, convert); } let subs: Iterable | undefined; @@ -119,7 +121,7 @@ function flatMapRawPusher( // eslint-disable-next-line @typescript-eslint/no-invalid-void-type let status: boolean | void; - const subsTail: PushIterator = itsHead(subs, element => status = accept(element)); + const subsTail: PushIterator = iterateIt(subs, element => status = accept(element)); subs = subsTail.isOver() ? undefined : subsTail; if (typeof status === 'boolean') { diff --git a/src/transformation/iterate-over-flattened-indexed.impl.ts b/src/transformation/iterate-over-flattened-indexed.impl.ts index 4f2f07d..8969e1f 100644 --- a/src/transformation/iterate-over-flattened-indexed.impl.ts +++ b/src/transformation/iterate-over-flattened-indexed.impl.ts @@ -1,7 +1,7 @@ import { makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import type { IndexedElements } from '../base/iterate-over-indexed.impl'; import { overNone } from '../construction'; -import { itsHead } from '../consumption'; import type { PushIterable } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; @@ -25,7 +25,7 @@ export function iterateOverFlattenedIndexed for (; ;) { let status: boolean | void; - const subsTail: PushIterator = itsHead(subs, element => status = accept(element)); + const subsTail: PushIterator = iterateIt(subs, element => status = accept(element)); if (subsTail.isOver()) { if (++i >= indexed.length) { diff --git a/src/transformation/map-array.spec.ts b/src/transformation/map-array.spec.ts index e1fe850..bd91129 100644 --- a/src/transformation/map-array.spec.ts +++ b/src/transformation/map-array.spec.ts @@ -1,5 +1,6 @@ import { describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements } from '../consumption'; import { mapArray } from './map-array'; @@ -24,9 +25,9 @@ describe('mapArray', () => { const result: string[] = []; const it = mapArray([11, 22, 33], element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['11!', '22!', '33!']); }); it('resumes conversion', () => { @@ -34,18 +35,18 @@ describe('mapArray', () => { const result: string[] = []; const it = mapArray([11, 22, 33], element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); expect([...it]).toHaveLength(0); }); diff --git a/src/transformation/map-indexed.spec.ts b/src/transformation/map-indexed.spec.ts index 9872f16..7552f9c 100644 --- a/src/transformation/map-indexed.spec.ts +++ b/src/transformation/map-indexed.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, pushIterated } from '../base'; +import { iteratorOf } from '../base'; +import { iterateIt } from '../base/iterate-it'; import type { IndexedItemList } from '../construction'; import { itsElements } from '../consumption'; import { mapIndexed } from './map-indexed'; @@ -40,9 +41,9 @@ describe('mapIndexed', () => { const result: string[] = []; const it = mapIndexed(list, element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['11!', '22!', '33!']); }); it('resumes conversion', () => { @@ -50,18 +51,18 @@ describe('mapIndexed', () => { const result: string[] = []; const it = mapIndexed(list, element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); expect([...it]).toHaveLength(0); }); diff --git a/src/transformation/map-it.spec.ts b/src/transformation/map-it.spec.ts index 622e703..fa6b134 100644 --- a/src/transformation/map-it.spec.ts +++ b/src/transformation/map-it.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, makePushIterator, pushIterated } from '../base'; +import { iteratorOf, makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { overMany } from '../construction'; import { itsElements } from '../consumption'; import { mapIt } from './map-it'; @@ -26,9 +27,9 @@ describe('mapIt', () => { const result: string[] = []; const it = mapIt(new Set([11, 22, 33]), element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['11!', '22!', '33!']); }); it('resumes conversion', () => { @@ -36,12 +37,12 @@ describe('mapIt', () => { const result: string[] = []; const it = mapIt(new Set([11, 22, 33]), element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); }); @@ -98,9 +99,9 @@ describe('mapIt', () => { const result: string[] = []; const it = mapIt(overMany(11, 22, 33), element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual(['11!', '22!', '33!']); }); it('resumes conversion', () => { @@ -108,12 +109,12 @@ describe('mapIt', () => { const result: string[] = []; const it = mapIt(overMany(11, 22, 33), element => `${element}!`)[Symbol.iterator](); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, element => { + expect(iterateIt(it, element => { result.push(element); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual(['22!', '33!']); }); diff --git a/src/transformation/map-it.ts b/src/transformation/map-it.ts index cdf33a9..15bca28 100644 --- a/src/transformation/map-it.ts +++ b/src/transformation/map-it.ts @@ -1,6 +1,7 @@ -import { isPushIterable, iteratorOf, makePushIterable, makePushIterator, pushHead } from '../base'; +import { isPushIterable, makePushIterable, makePushIterator } from '../base'; import { overNone } from '../construction'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; /** @@ -21,19 +22,19 @@ export function mapIt( ): PushIterable { return makePushIterable(accept => { - const forNext = isPushIterable(source) ? mapPusher(source, convert) : mapRawPusher(source, convert); + const forNext = isPushIterable(source) ? mapIt$(source, convert) : mapIt$raw(source, convert); return accept && !forNext(accept) ? overNone() : makePushIterator(forNext); }); } -function mapPusher( +function mapIt$( source: PushIterable, convert: (this: void, element: TSrc) => TConv, ): PushIterator.Pusher { return accept => { - const tail = pushHead(source, element => accept(convert(element))); + const tail = source[PushIterator__symbol](element => accept(convert(element))); source = tail; @@ -41,15 +42,15 @@ function mapPusher( }; } -function mapRawPusher( +function mapIt$raw( source: Iterable, convert: (this: void, element: TSrc) => TConv, ): PushIterator.Pusher { - const it = iteratorOf(source); + const it = source[Symbol.iterator](); if (isPushIterable(it)) { - return mapPusher(it, convert); + return mapIt$(it, convert); } return accept => { diff --git a/src/transformation/value-array.spec.ts b/src/transformation/value-array.spec.ts index 7200832..dbb64b6 100644 --- a/src/transformation/value-array.spec.ts +++ b/src/transformation/value-array.spec.ts @@ -1,5 +1,5 @@ import { describe, expect, it } from '@jest/globals'; -import { pushIterated } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { itsElements, itsIterator } from '../consumption'; import { valueArray } from './value-array'; @@ -18,7 +18,7 @@ describe('valueArray', () => { const it = itsIterator(valueArray([11, 22, 33], element => element > 11 && element + 100)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); expect([...it]).toEqual([133]); @@ -31,18 +31,18 @@ describe('valueArray', () => { const it = itsIterator(valueArray([11, 22, 33], element => element > 11 && element + 100)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([133]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([133]); }); }); diff --git a/src/transformation/value-indexed.spec.ts b/src/transformation/value-indexed.spec.ts index 474038f..a683b3c 100644 --- a/src/transformation/value-indexed.spec.ts +++ b/src/transformation/value-indexed.spec.ts @@ -1,5 +1,5 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { pushIterated } from '../base'; +import { iterateIt } from '../base/iterate-it'; import type { IndexedItemList } from '../construction'; import { itsElements, itsIterator } from '../consumption'; import { valueIndexed } from './value-indexed'; @@ -34,7 +34,7 @@ describe('valueIndexed', () => { const it = itsIterator(valueIndexed(list, element => element > 11 && element + 100)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); expect([...it]).toEqual([133]); @@ -47,18 +47,18 @@ describe('valueIndexed', () => { const it = itsIterator(valueIndexed(list, element => element > 11 && element + 100)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([133]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([133]); }); }); diff --git a/src/transformation/value-it.spec.ts b/src/transformation/value-it.spec.ts index 072b549..5ed4310 100644 --- a/src/transformation/value-it.spec.ts +++ b/src/transformation/value-it.spec.ts @@ -1,5 +1,6 @@ import { beforeEach, describe, expect, it } from '@jest/globals'; -import { iteratorOf, makePushIterator, pushIterated } from '../base'; +import { iteratorOf, makePushIterator } from '../base'; +import { iterateIt } from '../base/iterate-it'; import { overMany, overNone } from '../construction'; import { itsElements } from '../consumption'; import type { PushIterable } from '../push-iterable'; @@ -28,7 +29,7 @@ describe('valueIt', () => { const it = iteratorOf(valueIt(new Set([11, 22, 33]), element => element > 11 && element + 100)); - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect([...it]).toEqual([133]); expect([...it]).toHaveLength(0); @@ -38,18 +39,18 @@ describe('valueIt', () => { const it = iteratorOf(valueIt(new Set([11, 22, 33]), element => element > 11 && element + 100)); const result: number[] = []; - expect(pushIterated(it, () => true)).toBe(true); + expect(iterateIt(it, () => true).isOver()).toBe(false); expect(it.isOver()).toBe(false); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(it.isOver()).toBe(true); expect(result).toEqual([133]); - expect(pushIterated(it, el => { + expect(iterateIt(it, el => { result.push(el); - })).toBe(false); + }).isOver()).toBe(true); expect(result).toEqual([133]); }); @@ -71,7 +72,7 @@ describe('valueIt', () => { const it = iteratorOf(valueIt(new Set(), element => element > 11)); - expect(pushIterated(it, () => true)).toBe(false); + expect(iterateIt(it, () => true).isOver()).toBe(true); expect(it.isOver()).toBe(true); }); }); @@ -118,7 +119,7 @@ describe('valueIt', () => { const it = iteratorOf(iterable); - pushIterated(it, () => true); + iterateIt(it, () => true); expect(it.isOver()).toBe(false); expect([...it]).toEqual([133]); @@ -153,7 +154,7 @@ describe('valueIt', () => { const it = iteratorOf(iterable); - pushIterated(it, () => true); + iterateIt(it, () => true); expect(it.isOver()).toBe(false); expect([...it]).toEqual([133]); diff --git a/src/transformation/value-it.ts b/src/transformation/value-it.ts index 09d1ece..e91464c 100644 --- a/src/transformation/value-it.ts +++ b/src/transformation/value-it.ts @@ -1,6 +1,7 @@ -import { isPushIterable, iteratorOf, makePushIterable, makePushIterator, pushHead } from '../base'; +import { isPushIterable, makePushIterable, makePushIterator } from '../base'; import { overNone } from '../construction'; import type { PushIterable } from '../push-iterable'; +import { PushIterator__symbol } from '../push-iterable'; import type { PushIterator } from '../push-iterator'; /** @@ -23,32 +24,24 @@ export function valueIt( source: Iterable, valueOf: (this: void, element: T) => TValue | false | null | undefined, ): PushIterable { - return makePushIterable(accept => { - const forNext = isPushIterable(source) ? valuePusher(source, valueOf) : valueRawPusher(source, valueOf); + const forNext = isPushIterable(source) ? valueIt$(source, valueOf) : valueIt$raw(source, valueOf); - return accept && !forNext(accept) ? overNone() : makePushIterator(forNext); - }); + return makePushIterable(accept => accept && !forNext(accept) ? overNone() : makePushIterator(forNext)); } -function valuePusher( +function valueIt$( source: PushIterable, valueOf: (this: void, element: T) => TValue | false | null | undefined, ): PushIterator.Pusher { return accept => { - const tail = pushHead( - source, - element => { + const tail = source[PushIterator__symbol](element => { - const value = valueOf(element); + const value = valueOf(element); - if (value != null && value !== false) { - return accept(value); - } - return; - }, - ); + return value != null && value !== false ? accept(value) : void 0; + }); source = tail; @@ -56,15 +49,15 @@ function valuePusher( }; } -function valueRawPusher( +function valueIt$raw( source: Iterable, valueOf: (this: void, element: T) => TValue | false | null | undefined, ): PushIterator.Pusher { - const it = iteratorOf(source); + const it = source[Symbol.iterator](); if (isPushIterable(it)) { - return valuePusher(it, valueOf); + return valueIt$(it, valueOf); } return accept => {