From d5c3f3597b5b0ad7e39e49e8bf11ac54fa6b0089 Mon Sep 17 00:00:00 2001 From: hfutsora <346762712@qq.com> Date: Fri, 25 Nov 2022 11:47:42 +0800 Subject: [PATCH] feat(iterator): nth --- src/Iterator.ts | 32 +++++++++++++++++++++++++++++++- test/Iterator.spec.ts | 23 +++++++++++++++++------ 2 files changed, 48 insertions(+), 7 deletions(-) diff --git a/src/Iterator.ts b/src/Iterator.ts index f255e07..a41549c 100644 --- a/src/Iterator.ts +++ b/src/Iterator.ts @@ -75,6 +75,35 @@ export function* of(...as: A[]): Iterable { } } +/** + * Returns whether the index is out of bounds. + * + * @example + * + * ```ts + * assert.deepStrictEqual(pipe([1, 2, 3], isOutOfBounds(1)), false) + * assert.deepStrictEqual(pipe([1, 2, 3], isOutOfBounds(-1)), true) + * assert.deepStrictEqual(pipe([1, 2, 3], isOutOfBounds(3)), true) + * ``` + */ +export const isOutOfBounds = (index: number) => (as: Iterable): boolean => + index < 0 || index >= count(as) + + +/** + * Returns the value at the index of a iterator and wrapped in a Some if the index is not out of bounds. Otherwise returns a none. + * + * @example + * + * ```ts + * assert.deepStrictEqual(pipe([1, 2, 3], nth(1)), some(2)) + * assert.deepStrictEqual(pipe([1, 2, 3], nth(-1)), none) + * assert.deepStrictEqual(pipe([1, 2, 3], nth(3)), none) + * ``` + */ +export const nth = (index: number) => (as: Iterable): Maybe => + pipe(as, isOutOfBounds(index)) ? none : some(collect(as)[index]) + /** * Returns an empty list. * @returns @@ -544,7 +573,8 @@ export const chainRec = (f: (a: A) => Iterable>) => function* * assert.deepStrictEqual(iter([1]), new Iter(() => [1])) * ``` */ -export const iter = (ma: Iterable): Iter => new Iter(() => ma) +export const iter = (ma: Iterable | (() => Iterable)): Iter => + new Iter(typeof ma === 'function' ? ma : () => ma) /** * Iter diff --git a/test/Iterator.spec.ts b/test/Iterator.spec.ts index d19922f..281b2cc 100644 --- a/test/Iterator.spec.ts +++ b/test/Iterator.spec.ts @@ -1,5 +1,5 @@ import { left, right } from '../src/Either' -import { alt, ap, chain, chainRec, collect, concat, filter, isEmpty, iter, Iter, join, map, of, reduce, replicate, to, zero, tryTail, tryHead, group } from '../src/Iterator' +import { alt, ap, chain, chainRec, collect, concat, filter, isEmpty, iter, Iter, join, map, of, reduce, replicate, to, zero, tryTail, tryHead, group, nth } from '../src/Iterator' import { none, some } from '../src/Maybe' import { flow, pipe } from '../src/Pipe' @@ -47,7 +47,7 @@ it('range', () => { it('collect', () => { expect(iter([1, 2, 3]).collect()).toEqual([1, 2, 3]) - expect(new Iter(function* () { + expect(iter(function* () { for(let i = 1; i <= 3; i++) yield i }).collect()).toEqual([1, 2, 3]) }) @@ -56,7 +56,7 @@ it('join', () => { expect(flow(join('-'))(['a', 'b', 'c'])).toBe('a-b-c') expect(iter(['a', 'b', 'c']).join('-')).toBe('a-b-c') expect(iter(['a', 'b', 'c']).join()).toBe('a,b,c') - expect(new Iter(function* () { + expect(iter(function* () { yield 'a' yield 'b' yield 'c' @@ -65,7 +65,7 @@ it('join', () => { it('count', () => { expect(iter([1, 2, 3]).count()).toBe(3) - expect(new Iter(function* () { + expect(iter(function* () { yield 1 yield 2 yield 3 @@ -73,6 +73,17 @@ it('count', () => { expect(iter(new Set([1, 2, 3])).count()).toBe(3) }) +it('nth', () => { + expect(pipe([1, 2, 3], nth(0))).toEqual(some(1)) + expect(pipe([1, 2, 3], nth(3))).toEqual(none) + expect(pipe(new Set([1, 2, 3]), nth(0))).toEqual(some(1)) + expect(pipe(iter(function* () { + yield 1 + yield 2 + yield 3 + }), nth(0))).toEqual(some(1)) +}) + it('filter', () => { const f = flow( filter((a: number) => a % 2 === 0), @@ -87,7 +98,7 @@ it('filter', () => { it('zipWith', () => { expect(iter([1, 2, 3]).zipWith([0, 1], (a, b) => a + b).collect()).toEqual([1, 3]) expect(iter([1, 2]).zipWith([0, 1, 2], (a, b) => a + b).collect()).toEqual([1, 3]) - expect(new Iter(function* () { + expect(iter(function* () { yield 1 yield 2 yield 3 @@ -97,7 +108,7 @@ it('zipWith', () => { it('zip', () => { expect(iter([1, 2, 3]).zip([0, 1]).collect()).toEqual([[1, 0], [2, 1]]) expect(iter([1, 2]).zip([0, 1, 2]).collect()).toEqual([[1, 0], [2, 1]]) - expect(new Iter(function* () { + expect(iter(function* () { yield 1 yield 2 yield 3