Hyperlinkv0.8.0-beta.28

Stream

Stream.takeUntilconsteffect/Stream.ts:6413
<A>(
  predicate: (a: NoInfer<A>, n: number) => boolean,
  options?: { readonly excludeLast?: boolean | undefined }
): <E, R>(self: Stream<A, E, R>) => Stream<A, E, R>
<A, E, R>(
  self: Stream<A, E, R>,
  predicate: (a: A, n: number) => boolean,
  options?: { readonly excludeLast?: boolean | undefined }
): Stream<A, E, R>

Takes elements until the predicate matches.

Details

When excludeLast is true, the matching element is dropped.

Example (Taking until a predicate matches)

import { Console, Effect, Stream } from "effect"

const stream = Stream.range(1, 5)

const program = Effect.gen(function*() {
  const inclusive = yield* stream.pipe(
    Stream.takeUntil((n) => n % 3 === 0),
    Stream.runCollect
  )
  yield* Console.log(inclusive)
  // Output: [ 1, 2, 3 ]

  const exclusive = yield* stream.pipe(
    Stream.takeUntil((n) => n % 3 === 0, { excludeLast: true }),
    Stream.runCollect
  )
  yield* Console.log(exclusive)
  // Output: [ 1, 2 ]
})
filtering
Source effect/Stream.ts:641331 lines
export const takeUntil: {
  <A>(predicate: (a: NoInfer<A>, n: number) => boolean, options?: {
    readonly excludeLast?: boolean | undefined
  }): <E, R>(self: Stream<A, E, R>) => Stream<A, E, R>
  <A, E, R>(self: Stream<A, E, R>, predicate: (a: A, n: number) => boolean, options?: {
    readonly excludeLast?: boolean | undefined
  }): Stream<A, E, R>
} = dual(
  (args) => isStream(args[0]),
  <A, E, R>(self: Stream<A, E, R>, predicate: (a: A, n: number) => boolean, options?: {
    readonly excludeLast?: boolean | undefined
  }): Stream<A, E, R> =>
    transformPull(self, (pull, _scope) =>
      Effect.sync(() => {
        let i = 0
        let done = false
        const pump: Pull.Pull<Arr.NonEmptyReadonlyArray<A>, E, void, R> = Effect.flatMap(
          Effect.suspend(() => done ? Cause.done() : pull),
          (chunk) => {
            const index = chunk.findIndex((a) => predicate(a, i++))
            if (index >= 0) {
              done = true
              const arr = chunk.slice(0, options?.excludeLast ? index : index + 1)
              return Arr.isReadonlyArrayNonEmpty(arr) ? Effect.succeed(arr) : Cause.done()
            }
            return Effect.succeed(chunk)
          }
        )
        return pump
      }))
)
Referenced by 1 symbols