Hyperlinkv0.8.0-beta.28

Stream

Stream.rechunkconsteffect/Stream.ts:7032
(size: number): <A, E, R>(self: Stream<A, E, R>) => Stream<A, E, R>
<A, E, R>(self: Stream<A, E, R>, size: number): Stream<A, E, R>

Groups the stream into arrays of the specified size, preserving element order.

Details

The size is clamped to at least 1.

Example (Rechunking stream elements)

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

const program = Effect.gen(function*() {
  const result = yield* Stream.make(1, 2, 3, 4, 5).pipe(
    Stream.rechunk(2),
    Stream.chunks,
    Stream.runCollect
  )
  yield* Console.log(result)
})

Effect.runPromise(program)
// Output: [ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]
grouping
Source effect/Stream.ts:703248 lines
export const rechunk: {
  (size: number): <A, E, R>(self: Stream<A, E, R>) => Stream<A, E, R>
  <A, E, R>(self: Stream<A, E, R>, size: number): Stream<A, E, R>
} = dual(2, <A, E, R>(self: Stream<A, E, R>, target: number): Stream<A, E, R> => {
  target = Math.max(1, target)
  return transformPull(self, (pull, _scope) =>
    Effect.sync(() => {
      let chunk = Arr.empty<A>() as Arr.NonEmptyArray<A>
      let index = 0
      let current: Arr.NonEmptyReadonlyArray<A> | undefined
      let done = false

      return Effect.suspend(function loop(): Pull.Pull<Arr.NonEmptyReadonlyArray<A>, E, void, R> {
        if (done) return Cause.done()
        else if (current === undefined) {
          return Effect.flatMap(pull, (arr) => {
            if (chunk.length === 0 && arr.length === target) {
              return Effect.succeed(arr)
            } else if (chunk.length + arr.length < target) {
              chunk.push(...arr)
              return loop()
            }
            current = arr
            return loop()
          })
        }
        for (; index < current.length;) {
          chunk.push(current[index++])
          if (chunk.length === target) {
            const result = chunk
            chunk = [] as any
            return Effect.succeed(result)
          }
        }
        index = 0
        current = undefined
        return loop()
      }).pipe(
        Pull.catchDone(() => {
          if (chunk.length === 0) return Cause.done()
          const result = chunk
          done = true
          chunk = [] as any
          return Effect.succeed(result)
        })
      )
    }))
})
Referenced by 1 symbols