Add limit and limitAsync (#1)
* Fix tests for iterable * Add limit and limitAsync functions
This commit is contained in:
1 parent
9646b31cfd
commit
3b8138d4fe
2 files changed
+73
-6
No files matched your search
+34
-2
@@ -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<T>(count: number, iterable: Iterable<T>) {
|
||||
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<T>(count: number, iterable: AsyncIterable<T>) {
|
||||
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<T>(arr: T[]): T[] {
|
||||
* @since 2020-07-19
|
||||
*/
|
||||
export function swap<T>(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<T>(source: AsyncIterable<T>, predicate: (value: T) =>
|
||||
* @author MindfulMinun
|
||||
* @since 2022-06-05
|
||||
*/
|
||||
export function pinkyPromise<T>(): [Promise<T>, (value: T) => void, (error: any) => unknown] {
|
||||
export function pinkyPromise<T>(): [Promise<T>, (value: T) => void, (error: unknown) => unknown] {
|
||||
let resolve: (value: T) => void
|
||||
let reject: (error: unknown) => void
|
||||
|
||||
|
||||
+39
-4
@@ -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/[email protected]/testing/asserts.ts"
|
||||
@@ -29,12 +29,47 @@ Deno.test("range: one arg", () => {
|
||||
assert(iter.next().done)
|
||||
})
|
||||
|
||||
|
||||
Deno.test("range: two args", () => {
|
||||
const iter = range(50_000)
|
||||
for (let i = 0; i < 50_000; i++) {
|
||||
const iter = range(40, 50)
|
||||
for (let i = 40; i < 50; i++) {
|
||||
const next = iter.next()
|
||||
assertEquals(next.value, i)
|
||||
}
|
||||
assert(iter.next().done)
|
||||
})
|
||||
|
||||
Deno.test("range: three args", () => {
|
||||
const iter = range(60, 80, 4)
|
||||
for (let i = 60; i < 80; i += 4) {
|
||||
const next = iter.next()
|
||||
assertEquals(next.value, i)
|
||||
}
|
||||
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
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user