โ Back to Design Patterns
๐
Behavioral
Iterator
Provides a way to sequentially access elements of a collection without exposing its underlying representation.
The Problem
A collection has a complex internal structure (tree, graph, ring buffer). You want to iterate over it without exposing how the data is stored.
How It Works
- โบSeparates traversal logic from the collection class
- โบSupports multiple simultaneous independent traversals of the same collection
- โบEnables a unified for-in / for-of interface across all collections
- โบLazy iterators (Kotlin Sequences, Python generators) compute elements on demand
- โบInternal iterator hides the loop; external iterator gives the caller control
When to Use
โCustom collections that need to support for-in/for-of loops
โWhen you need multiple traversal strategies for the same collection
โHiding complex traversal logic (tree traversal, pagination)
โLazy sequences where computing all elements upfront is expensive
Real-World Examples
๐
iOS
IteratorProtocol + Sequence, IndexingIterator, for-in on any Collection type
๐ค
Android
Iterable<T>, Kotlin Sequences for lazy evaluation, Cursor for database rows
๐
Web
Symbol.iterator, Generator functions (function*), built-in Array/Map/Set iterators
Code Examples
Swift
struct Countdown: Sequence {
let from: Int
func makeIterator() -> CountdownIterator {
CountdownIterator(current: from)
}
struct CountdownIterator: IteratorProtocol {
var current: Int
mutating func next() -> Int? {
guard current >= 0 else { return nil }
defer { current -= 1 }
return current
}
}
}
let countdown = Countdown(from: 5)
for n in countdown { print(n) } // 5, 4, 3, 2, 1, 0
// Works with all Sequence methods
print(countdown.contains(3)) // true
print(Array(countdown)) // [5, 4, 3, 2, 1, 0]