Skip to content

Commit

Permalink
Add joinToString()
Browse files Browse the repository at this point in the history
  • Loading branch information
Cody Casterline committed Jul 16, 2023
1 parent c063c51 commit cc65750
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 0 deletions.
27 changes: 27 additions & 0 deletions mod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ interface LazyShared<T> {
/** Flattens a Lazy<Iterable<T>> to a Lazy<T> */
flatten(): LazyShared<Flattened<T>>

/** Joins multiple string values into a string. */
joinToString(args?: JoinToStringArgs): Awaitable<JoinedToString<T>>

/** Fold values. See example in {@link LazyShared#sum} */
fold<I>(initialValue: I, foldFn: (i: I, t: T) => I): Awaitable<I>

Expand Down Expand Up @@ -469,6 +472,12 @@ export class Lazy<T> implements Iterable<T>, LazyShared<T> {
}())
}

/** Joins multiple string values into a string. */
joinToString(args?: JoinToStringArgs): JoinedToString<T> {
const sep = args?.sep ?? ", "
return this.toArray().join(sep) as JoinedToString<T>
}

/** Collect all items into an array. */
toArray(): Array<T> {
return [... this.#inner]
Expand Down Expand Up @@ -874,6 +883,12 @@ export class LazyAsync<T> implements AsyncIterable<T>, LazyShared<T> {
}())
}

/** Joins multiple string values into a string. */
async joinToString(args?: JoinToStringArgs): Promise<JoinedToString<T>> {
const sep = args?.sep ?? ", "
return (await this.toArray()).join(sep) as JoinedToString<T>
}

/** Collect all items into an array. */
async toArray(): Promise<T[]> {
let out: T[] = []
Expand Down Expand Up @@ -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> = T extends string ? string : never

const rangeArgsDefaults: Required<RangeArgs> = {
from: 0,
to: Number.MAX_SAFE_INTEGER,
Expand Down
42 changes: 42 additions & 0 deletions tests/main_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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}`
}

0 comments on commit cc65750

Please sign in to comment.