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