Hyperlinkv0.8.0-beta.28

Iterable

Iterable.filterMapWhileconsteffect/Iterable.ts:1722
<A, B, X>(f: (input: A, i: number) => Result<B, X>): (
  self: Iterable<A>
) => Iterable<B>
<A, B, X>(
  self: Iterable<A>,
  f: (input: A, i: number) => Result<B, X>
): Iterable<B>

Transforms all elements of the Iterable for as long as the specified function succeeds.

Example (Filtering and transforming until failure)

import { Iterable, Result } from "effect"

// Parse numbers until we hit an invalid one
const strings = ["1", "2", "3", "invalid", "4", "5"]
const numbers = Iterable.filterMapWhile(strings, (s) => {
  const num = parseInt(s)
  return isNaN(num) ? Result.failVoid : Result.succeed(num)
})
console.log(Array.from(numbers)) // [1, 2, 3] (stops at "invalid")

// Take elements while they meet a condition and transform them
const values = [2, 4, 6, 7, 8, 10]
const doubledEvens = Iterable.filterMapWhile(
  values,
  (n) => n % 2 === 0 ? Result.succeed(n * 2) : Result.failVoid
)
console.log(Array.from(doubledEvens)) // [4, 8, 12] (stops at 7)

// Process with index until condition fails
const letters = ["a", "b", "c", "d", "e"]
const indexedUntilC = Iterable.filterMapWhile(
  letters,
  (letter, i) => letter !== "c" ? Result.succeed(`${i}: ${letter}`) : Result.failVoid
)
console.log(Array.from(indexedUntilC)) // ["0: a", "1: b"] (stops at "c")
filtering
export const filterMapWhile: {
  <A, B, X>(f: (input: A, i: number) => Result<B, X>): (self: Iterable<A>) => Iterable<B>
  <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>): Iterable<B>
} = dual(2, <A, B, X>(self: Iterable<A>, f: (input: A, i: number) => Result<B, X>) => ({
  [Symbol.iterator]() {
    const iterator = self[Symbol.iterator]()
    let i = 0
    return {
      next() {
        const result = iterator.next()
        if (result.done) {
          return { done: true, value: undefined }
        }
        const next = f(result.value, i++)
        if (R.isSuccess(next)) {
          return { done: false, value: next.success }
        }
        return { done: true, value: undefined }
      }
    }
  }
}))