diff --git a/iterable.ts b/iterable.ts index ef9f059..0a5d5d0 100644 --- a/iterable.ts +++ b/iterable.ts @@ -48,6 +48,38 @@ export function* range(a: number, b?: number, c?: number) { yield i } +/** + * Given an iterable, yields the first `count` items, then returns. + * @author MindfulMinun + * @since 2022-07-07 + */ +export function* limit(count: number, iterable: Iterable) { + let i = 0 + for (const value of iterable) { + if (i < count) { + yield value + i++ + } else break + } + return iterable +} + +/** + * Given an async iterable, yields the first `count` items, then returns. + * @author MindfulMinun + * @since 2022-07-07 + */ +export async function* limitAsync(count: number, iterable: AsyncIterable) { + let i = 0 + for await (const value of iterable) { + if (i < count) { + yield value + i++ + } else break + } + return iterable +} + /** * Removes elements from an array. Non-destructive, as all array operations should be :D * @@ -106,7 +138,7 @@ export function shuffle(arr: T[]): T[] { * @since 2020-07-19 */ export function swap(arr: T[], i: number, j: number): void { - let carry = arr[i] + const carry = arr[i] arr[i] = arr[j] arr[j] = carry } @@ -217,7 +249,7 @@ export async function once(source: AsyncIterable, predicate: (value: T) => * @author MindfulMinun * @since 2022-06-05 */ -export function pinkyPromise(): [Promise, (value: T) => void, (error: any) => unknown] { +export function pinkyPromise(): [Promise, (value: T) => void, (error: unknown) => unknown] { let resolve: (value: T) => void let reject: (error: unknown) => void diff --git a/tests/iterable.test.ts b/tests/iterable.test.ts index 9282869..6289402 100644 --- a/tests/iterable.test.ts +++ b/tests/iterable.test.ts @@ -1,5 +1,5 @@ import { - choose, fill, range, removeFromArraybyIndexes, shuffle, swap, once + choose, fill, range, limit } from "../iterable.ts" import { assertThrows, assertEquals, assert } from "https://deno.land/std@0.140.0/testing/asserts.ts" @@ -46,3 +46,30 @@ Deno.test("range: three args", () => { } assert(iter.next().done) }) + + +Deno.test("limit: limits to the first n elements", () => { + const values: number[] = [] + const truth = [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584, 4181] + const count = truth.length + for (const value of limit(count, fibonacci())) { + values.push(value) + } + assertEquals(values.length, count) + truth.forEach((val, i) => { + assertEquals(values[i], val) + }) +}) + +function* fibonacci() { + let back2 = 0 + let back1 = 1 + yield back2 + yield back1 + while (true) { + const sum = back2 + back1 + back2 = back1 + back1 = sum + yield sum + } +}