Iterator Pattern
Access elements sequentially without exposing underlying structure
Pattern Overview
π Iterator Pattern
The Iterator Pattern provides a way to access elements of a collection sequentially without exposing the underlying representation. It separates the traversal logic from the collection structure.
Core Concepts
πΉ Iterator Interface - Defines methods for traversing elements (hasNext, next, reset)
πΉ Concrete Iterator - Implements traversal logic for specific collections
πΉ Iterable Interface - Collection that can create iterators
πΉ External Iteration - Client controls iteration process
Real-World Applications
Data Structures - Arrays, lists, trees, graphs with different traversal strategies File Systems - Directory traversal with various filtering and ordering options Database Results - Process query results without loading all data into memory Streaming Data - Process large datasets one element at a timeTraversal Strategies
Linear Collections - Forward, reverse, filtered iteration Tree Structures - Pre-order, post-order, level-order traversal Custom Logic - Skip elements, transform values, conditional processing Lazy Evaluation - Generate elements on-demand without storing entire collectionImplementation Benefits
β
Encapsulation - Internal structure hidden from client code
β
Multiple traversals - Different iterators can traverse same collection
β
Uniform interface - Same iteration pattern across different data structures
β
Memory efficiency - Process large collections without loading everything
Examples:
const library = createBookLibrary();
console.log('All books:');
iteratorForEach(library.createIterator(), book =>
console.log(book.toString())
);
console.log('\nDystopian books:');
iteratorForEach(library.createGenreIterator('Dystopian'), book =>
console.log(book.toString())
);
console.log('\nReverse order:');
const reverseBooks = iteratorCollect(library.createReverseIterator());
console.log(reverseBooks.slice(0, 3).map(b => b.title).join(', '));All books:
"1984" by George Orwell (1949)
"Brave New World" by Aldous Huxley (1932)
"The Hobbit" by J.R.R. Tolkien (1937)
...
Dystopian books:
"1984" by George Orwell (1949)
"Brave New World" by Aldous Huxley (1932)
Reverse order:
Neuromancer, Foundation, Duneconst tree = createFileSystemTree();
console.log('Pre-order traversal:');
const preOrder = iteratorCollect(tree.createPreOrderIterator());
console.log(preOrder.slice(0, 5).join(' β '));
console.log('\nLevel-order traversal:');
const levelOrder = iteratorCollect(tree.createLevelOrderIterator());
console.log(levelOrder.slice(0, 5).join(' β '));Pre-order traversal:
root/ β src/ β index.js β utils.js β lib/
Level-order traversal:
root/ β src/ β lib/ β test/ β package.jsonconst ranges = createNumberRanges();
console.log('Standard range (1-10):');
console.log(iteratorCollect(ranges.standard.createIterator()).join(', '));
console.log('\nEven numbers (0-20, step 2):');
console.log(iteratorCollect(ranges.step2.createEvenIterator()).join(', '));
console.log('\nReverse range (5 to -5):');
console.log(iteratorCollect(ranges.negative.createReverseIterator()).join(', '));Standard range (1-10):
1, 2, 3, 4, 5, 6, 7, 8, 9, 10
Even numbers (0-20, step 2):
0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
Reverse range (5 to -5):
-5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5Concepts
Complexity Analysis
Implementation
book-collection
// Book collection with filtered iteration
class Book {
constructor(
public title: string,
public author: string,
public year: number,
public genre: string
) {}
toString(): string {
return `"${this.title}" by ${this.author} (${this.year})`;
}
}
class BookCollection implements Iterable<Book> {
private books: Book[] = [];
addBook(book: Book): void {
this.books.push(book);
}
createIterator(): Iterator<Book> {
return new BookIterator(this.books);
}
createGenreIterator(genre: string): Iterator<Book> {
return new GenreFilterIterator(this.books, genre);
}
createReverseIterator(): Iterator<Book> {
return new ReverseBookIterator(this.books);
}
}
class BookIterator implements Iterator<Book> {
private index = 0;
constructor(private books: Book[]) {}
hasNext(): boolean {
return this.index < this.books.length;
}
next(): Book | null {
if (this.hasNext()) {
return this.books[this.index++];
}
return null;
}
reset(): void {
this.index = 0;
}
}