Jump into concepts and practice - no test required
or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Recall & Review
beginner
What is the Iterator pattern?
The Iterator pattern is a design pattern that provides a way to access elements of a collection one by one without exposing its underlying structure.
Click to reveal answer
beginner
Name the two main roles in the Iterator pattern.
The two main roles are: 1) Iterator - defines methods to traverse elements, and 2) Aggregate (or Collection) - provides a method to create an iterator.
Click to reveal answer
intermediate
Why use the Iterator pattern instead of directly accessing a collection?
It hides the internal structure of the collection and allows different ways to traverse it without changing the collection's code.
Click to reveal answer
intermediate
What methods are typically defined in an Iterator interface?
Common methods include: 1) hasNext() - checks if more elements exist, 2) next() - returns the next element, and sometimes 3) remove() - removes the current element.
Click to reveal answer
beginner
Give a real-life example that explains the Iterator pattern.
Think of a TV remote to change channels. You don’t need to know how the TV stores channels; you just press next or previous to move through them one by one.
Click to reveal answer
What does the Iterator pattern help to achieve?
ATraverse elements without exposing collection structure
BStore elements in a collection
CSort elements in a collection
DCreate new collections
✗ Incorrect
The Iterator pattern allows traversal of elements without exposing the underlying collection structure.
Which method is NOT typically part of an Iterator interface?
AhasNext()
Bnext()
Cadd()
Dremove()
✗ Incorrect
add() is not usually part of the Iterator interface; it is a collection operation.
In the Iterator pattern, who creates the iterator?
AAggregate or collection
BIterator itself
CClient code
DExternal factory
✗ Incorrect
The aggregate or collection provides a method to create an iterator.
Which of these is a benefit of using the Iterator pattern?
AAutomatic data backup
BDirect access to collection internals
CFaster sorting
DMultiple traversal methods without changing collection
✗ Incorrect
Iterator pattern allows different ways to traverse without changing the collection.
What is the main purpose of the hasNext() method?
AReturn the current element
BCheck if more elements exist
CRemove the current element
DAdd a new element
✗ Incorrect
hasNext() checks if there are more elements to iterate over.
Explain the Iterator pattern and its main components in your own words.
Think about how you would explain browsing a list without seeing how it is stored.
You got /3 concepts.
Describe a real-life scenario that illustrates the Iterator pattern and why it is useful.
Consider everyday tools that let you move through items one by one.
You got /3 concepts.
Practice
(1/5)
1.
What is the main purpose of the Iterator pattern in system design?
easy
A. To manage user authentication and authorization
B. To store data in a database efficiently
C. To create multiple copies of an object
D. To provide a way to access elements of a collection sequentially without exposing its underlying structure
Solution
Step 1: Understand the role of Iterator pattern
The Iterator pattern is designed to provide a way to access elements of a collection one by one without revealing the internal structure of the collection.
Step 2: Compare with other options
Options B, C, and D describe unrelated design patterns or system functions such as data storage, object cloning, and security management.
Final Answer:
To provide a way to access elements of a collection sequentially without exposing its underlying structure -> Option D
Quick Check:
Iterator pattern = Access collection without exposing structure [OK]
Hint: Iterator = access elements without showing internal details [OK]
Common Mistakes:
Confusing Iterator with data storage or cloning patterns
Thinking Iterator manages security or authentication
Assuming Iterator modifies the collection
2.
Which of the following is the correct method signature for the next() method in an iterator interface?
easy
A. def next() -> void
B. def next(self, index) -> Element
C. def next(self) -> Element
D. def next(self, element) -> bool
Solution
Step 1: Recall the standard iterator method signature
The next() method typically takes no parameters except the implicit self and returns the next element in the collection.
Step 2: Analyze each option
def next(self) -> Element matches the standard signature: it takes self and returns an element. Options B and D incorrectly add parameters, and C returns void which is incorrect.
Final Answer:
def next(self) -> Element -> Option C
Quick Check:
next() takes no args, returns element [OK]
Hint: next() returns next element, no extra parameters [OK]
Common Mistakes:
Adding parameters to next() method
Returning void instead of element
Confusing next() with hasNext() method
3.
Consider the following Python code implementing a simple iterator:
class MyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index < len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
it = MyIterator([10, 20, 30])
print(next(it))
print(next(it))
What will be the output?
medium
A. 20\n30
B. 10\n20
C. 10\n30
D. Error at runtime
Solution
Step 1: Trace the iterator's next calls
First call to next(it) returns data[0] = 10 and increments index to 1. Second call returns data[1] = 20 and increments index to 2.
Step 2: Confirm no errors occur
Since index is less than length during both calls, no StopIteration is raised.
Final Answer:
10
20 -> Option B
Quick Check:
First two elements printed: 10 and 20 [OK]
Hint: next() returns elements in order, increments index [OK]
Common Mistakes:
Assuming next() skips elements
Expecting error before StopIteration
Mixing up index increments
4.
Given this iterator implementation in Python, identify the bug:
class BuggyIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if self.index <= len(self.data):
result = self.data[self.index]
self.index += 1
return result
else:
raise StopIteration
What is the cause of the error when iterating?
medium
A. IndexError due to accessing out-of-range element
B. StopIteration raised too early
C. Infinite loop because index never increments
D. Syntax error in method definitions
Solution
Step 1: Analyze the condition in __next__
The condition uses <= len(self.data), which allows index to equal length, causing out-of-range access.
Step 2: Understand the error caused
Accessing self.data[self.index] when index == len(self.data) causes IndexError because list indices go from 0 to len-1.
Final Answer:
IndexError due to accessing out-of-range element -> Option A
Quick Check:
Condition allows index == length causing IndexError [OK]
Hint: Use < not <= to avoid out-of-range errors [OK]
Common Mistakes:
Using <= instead of < in boundary check
Assuming StopIteration triggers before error
Ignoring index increment effects
5.
You need to design an iterator for a complex data structure that contains nested lists of integers. Which approach best follows the Iterator pattern principles to allow clients to iterate over all integers seamlessly?
Flatten the nested lists into a single list before iteration.
Implement a recursive iterator that yields integers from nested lists on demand.
Expose the internal nested list structure and let clients handle iteration.
Provide separate iterators for each nested list and require clients to manage them.
hard
A. Implement a recursive iterator that yields integers from nested lists on demand
B. Flatten the nested lists into a single list before iteration
C. Expose the internal nested list structure and let clients handle iteration
D. Provide separate iterators for each nested list and require clients to manage them
Solution
Step 1: Understand Iterator pattern goal
The pattern aims to hide internal structure and provide a simple way to access elements sequentially.
Step 2: Evaluate each approach
Flatten the nested lists into a single list before iteration flattens data upfront, which may be inefficient and breaks lazy access. Implement a recursive iterator that yields integers from nested lists on demand uses a recursive iterator to yield elements on demand, hiding complexity and supporting lazy iteration. Options C and D expose internal structure or complexity to clients, violating encapsulation.
Final Answer:
Implement a recursive iterator that yields integers from nested lists on demand -> Option A
Quick Check:
Recursive iterator hides structure, yields elements lazily [OK]
Hint: Use recursive iterator to hide nested structure [OK]
Common Mistakes:
Flattening data upfront losing lazy iteration benefits