| 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 |
Use take to limit how many elements to process. Use drop to skip elements. Add While variants for condition-based limits.
Streams can be infinite or very large. These operators let you:
- Limit processing - Only take what you need
- Skip headers - Drop first N elements
- Conditional limits - Take/drop based on predicates
- Pagination - Implement skip/limit patterns
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"]
})
| 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
)