From cc65750423bd77f2547224075bb08a9735bed737 Mon Sep 17 00:00:00 2001 From: Cody Casterline Date: Sun, 16 Jul 2023 12:56:09 -0700 Subject: [PATCH] Add joinToString() --- mod.ts | 27 +++++++++++++++++++++++++++ tests/main_test.ts | 42 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/mod.ts b/mod.ts index 2791339..fa22d3f 100644 --- a/mod.ts +++ b/mod.ts @@ -216,6 +216,9 @@ interface LazyShared { /** Flattens a Lazy> to a Lazy */ flatten(): LazyShared> + /** Joins multiple string values into a string. */ + joinToString(args?: JoinToStringArgs): Awaitable> + /** Fold values. See example in {@link LazyShared#sum} */ fold(initialValue: I, foldFn: (i: I, t: T) => I): Awaitable @@ -469,6 +472,12 @@ export class Lazy implements Iterable, LazyShared { }()) } + /** Joins multiple string values into a string. */ + joinToString(args?: JoinToStringArgs): JoinedToString { + const sep = args?.sep ?? ", " + return this.toArray().join(sep) as JoinedToString + } + /** Collect all items into an array. */ toArray(): Array { return [... this.#inner] @@ -874,6 +883,12 @@ export class LazyAsync implements AsyncIterable, LazyShared { }()) } + /** Joins multiple string values into a string. */ + async joinToString(args?: JoinToStringArgs): Promise> { + const sep = args?.sep ?? ", " + return (await this.toArray()).join(sep) as JoinedToString + } + /** Collect all items into an array. */ async toArray(): Promise { let out: T[] = [] @@ -1070,6 +1085,18 @@ export interface RangeArgs { inclusive?: boolean } +export interface JoinToStringArgs { + /** The separator to use. Default: ", " */ + sep?: string + + // Can add more join options here if people want. +} + +/** + * Only `string` values can be joined to string + */ +export type JoinedToString = T extends string ? string : never + const rangeArgsDefaults: Required = { from: 0, to: Number.MAX_SAFE_INTEGER, diff --git a/tests/main_test.ts b/tests/main_test.ts index 0b10d83..e3e11d0 100644 --- a/tests/main_test.ts +++ b/tests/main_test.ts @@ -286,3 +286,45 @@ Deno.test(async function avg(t) { assertEquals(await iter.avg(), 4.5) }) }) + +Deno.test(async function joinToString(t) { + const input = () => range({from: 14, to: 21}) + await testBoth(t, input, async (iter) => { + let result = await iter + .map(num => `${num}: ${fizzBuzz(num)}`) + .joinToString() + assertEquals(result, "14: 14, 15: FizzBuzz, 16: 16, 17: 17, 18: Fizz, 19: 19, 20: Buzz") + }) +}) + +Deno.test(async function joinToStringWithSep(t) { + const input = () => range({from: 14, to: 21}) + await testBoth(t, input, async (iter) => { + let result = await iter + .map(num => `${num}: ${fizzBuzz(num)}`) + .joinToString({sep: "X"}) + assertEquals(result, "14: 14X15: FizzBuzzX16: 16X17: 17X18: FizzX19: 19X20: Buzz") + }) +}) + +Deno.test(async function joinToStringEmpty(t) { + await testBoth(t, [], async (iter) => { + let result = await iter + .joinToString() + + assertEquals(result, "") + }) +}) + +function fizzBuzz(num: number) { + if (num % 15 == 0) { + return "FizzBuzz" + } + if (num % 5 == 0) { + return "Buzz" + } + if (num % 3 == 0) { + return "Fizz" + } + return `${num}` +} \ No newline at end of file