Skip to content

Latest commit

 

History

History
172 lines (135 loc) · 3.96 KB

File metadata and controls

172 lines (135 loc) · 3.96 KB
title Take and Drop Stream Elements
id stream-take-drop
skillLevel beginner
applicationPatternId streams-getting-started
summary Control how many stream elements to process using take, drop, takeWhile, and dropWhile.
tags
stream
take
drop
slice
limit
rule
description
Use take/drop to control stream size, takeWhile/dropWhile for conditional limits.
author PaulJPhilp
related
stream-hello-world
stream-map-filter
lessonOrder 4

Guideline

Use take to limit how many elements to process. Use drop to skip elements. Add While variants for condition-based limits.


Rationale

Streams can be infinite or very large. These operators let you:

  1. Limit processing - Only take what you need
  2. Skip headers - Drop first N elements
  3. Conditional limits - Take/drop based on predicates
  4. Pagination - Implement skip/limit patterns

Good Example

import { Effect, Stream } from "effect"

const numbers = Stream.make(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)

// ============================================
// take - Get first N elements
// ============================================

const firstThree = numbers.pipe(
  Stream.take(3),
  Stream.runCollect
)

Effect.runPromise(firstThree).then((chunk) => {
  console.log([...chunk])  // [1, 2, 3]
})

// ============================================
// drop - Skip first N elements
// ============================================

const skipThree = numbers.pipe(
  Stream.drop(3),
  Stream.runCollect
)

Effect.runPromise(skipThree).then((chunk) => {
  console.log([...chunk])  // [4, 5, 6, 7, 8, 9, 10]
})

// ============================================
// Combine for pagination (skip + limit)
// ============================================

const page2 = numbers.pipe(
  Stream.drop(3),   // Skip first page
  Stream.take(3),   // Take second page
  Stream.runCollect
)

Effect.runPromise(page2).then((chunk) => {
  console.log([...chunk])  // [4, 5, 6]
})

// ============================================
// takeWhile - Take while condition is true
// ============================================

const untilFive = numbers.pipe(
  Stream.takeWhile((n) => n < 5),
  Stream.runCollect
)

Effect.runPromise(untilFive).then((chunk) => {
  console.log([...chunk])  // [1, 2, 3, 4]
})

// ============================================
// dropWhile - Skip while condition is true
// ============================================

const afterFive = numbers.pipe(
  Stream.dropWhile((n) => n < 5),
  Stream.runCollect
)

Effect.runPromise(afterFive).then((chunk) => {
  console.log([...chunk])  // [5, 6, 7, 8, 9, 10]
})

// ============================================
// takeUntil - Take until condition becomes true
// ============================================

const untilSix = numbers.pipe(
  Stream.takeUntil((n) => n === 6),
  Stream.runCollect
)

Effect.runPromise(untilSix).then((chunk) => {
  console.log([...chunk])  // [1, 2, 3, 4, 5, 6]
})

// ============================================
// Practical: Process file with header
// ============================================

const fileLines = Stream.make(
  "# Header",
  "# Comment",
  "data1",
  "data2",
  "data3"
)

const dataOnly = fileLines.pipe(
  Stream.dropWhile((line) => line.startsWith("#")),
  Stream.runCollect
)

Effect.runPromise(dataOnly).then((chunk) => {
  console.log([...chunk])  // ["data1", "data2", "data3"]
})

Quick Reference

Operator Behavior
take(n) First N elements only
drop(n) Skip first N elements
takeWhile(pred) Take while predicate is true
dropWhile(pred) Skip while predicate is true
takeUntil(pred) Take until predicate becomes true (inclusive)
dropUntil(pred) Skip until predicate becomes true

Pagination Pattern

const getPage = (pageNum: number, pageSize: number) =>
  allItems.pipe(
    Stream.drop(pageNum * pageSize),
    Stream.take(pageSize),
    Stream.runCollect
  )