Bird
Raised Fist0
Swiftprogramming~5 mins

Sequence protocol for custom iteration in Swift - Cheat Sheet & Quick Revision

Choose your learning style10 modes available
Recall & Review
beginner
What is the Sequence protocol in Swift?
The Sequence protocol defines a type that can be iterated over, providing a way to access elements one by one in order.
Click to reveal answer
beginner
Which method must a type implement to conform to the Sequence protocol?
It must implement the makeIterator() method, which returns an iterator conforming to the IteratorProtocol.
Click to reveal answer
intermediate
What does the IteratorProtocol require?
It requires a next() method that returns the next element or nil when no more elements are available.
Click to reveal answer
beginner
How can you use a custom sequence in a for-in loop?
Once your type conforms to Sequence, you can use it directly in a for-in loop to iterate over its elements.
Click to reveal answer
intermediate
Why create a custom sequence instead of using arrays?
Custom sequences allow you to define how elements are generated or accessed, which can save memory or represent infinite or complex data streams.
Click to reveal answer
What does the makeIterator() method return?
AA single element
BAn iterator conforming to <code>IteratorProtocol</code>
CAn array of elements
DA closure
What should the next() method return when the sequence ends?
A<code>nil</code>
BThe last element again
CAn empty string
DZero
Which Swift protocol must an iterator conform to?
AIteratorProtocol
BSequence
CCollection
DEquatable
Can a custom sequence be infinite?
AOnly if it conforms to Collection
BNo, sequences must have an end
COnly if it uses arrays internally
DYes, if <code>next()</code> never returns <code>nil</code>
What is the benefit of conforming to Sequence?
APrevents iteration
BMakes the type immutable
CAllows use in <code>for-in</code> loops and sequence functions
DAutomatically sorts elements
Explain how to create a custom sequence in Swift using the Sequence protocol.
Think about how the sequence produces an iterator and how the iterator produces elements.
You got /4 concepts.
    Describe the role of the IteratorProtocol in custom iteration.
    Focus on how iteration progresses step-by-step.
    You got /4 concepts.

      Practice

      (1/5)
      1. What does the Sequence protocol in Swift require you to provide for custom iteration?
      easy
      A. A property that stores all elements in an array
      B. A method named start() that begins the iteration
      C. A function that returns the count of elements
      D. An iterator with a next() method that returns elements or nil

      Solution

      1. Step 1: Understand the Sequence protocol requirement

        The Sequence protocol requires an iterator that can provide elements one by one.
      2. Step 2: Identify the iterator method

        This iterator must have a next() method that returns the next element or nil when done.
      3. Final Answer:

        An iterator with a next() method that returns elements or nil -> Option D
      4. Quick Check:

        Sequence needs next() iterator method = C [OK]
      Hint: Sequence needs an iterator with next() returning nil at end [OK]
      Common Mistakes:
      • Thinking Sequence requires a start() method
      • Assuming all elements must be stored in an array
      • Confusing count with iteration method
      2. Which of the following is the correct way to declare a custom iterator type conforming to IteratorProtocol in Swift?
      easy
      A. struct MyIterator: IteratorProtocol { func next() -> Int { return 0 } }
      B. class MyIterator { func next() -> Int { return 0 } }
      C. struct MyIterator: Sequence { func next() -> Int? { return nil } }
      D. struct MyIterator: IteratorProtocol { func next() -> Int? { return nil } }

      Solution

      1. Step 1: Check protocol conformance and method signature

        IteratorProtocol requires a next() method returning an optional element type, here Int?.
      2. Step 2: Validate each option

        struct MyIterator: IteratorProtocol { func next() -> Int? { return nil } } correctly declares a struct conforming to IteratorProtocol with next() -> Int?. class MyIterator { func next() -> Int { return 0 } } lacks conformance and returns non-optional. struct MyIterator: Sequence { func next() -> Int? { return nil } } wrongly conforms to Sequence, not IteratorProtocol. struct MyIterator: IteratorProtocol { func next() -> Int { return 0 } } returns non-optional Int, which is incorrect.
      3. Final Answer:

        struct MyIterator: IteratorProtocol { func next() -> Int? { return nil } } -> Option A
      4. Quick Check:

        IteratorProtocol requires next() returning optional = D [OK]
      Hint: IteratorProtocol's next() must return optional element type [OK]
      Common Mistakes:
      • Returning non-optional from next()
      • Confusing Sequence with IteratorProtocol
      • Missing protocol conformance declaration
      3. Consider this Swift code implementing a custom sequence:
      struct CountDown: Sequence {
        let start: Int
        func makeIterator() -> some IteratorProtocol {
          var current = start
          return AnyIterator {
            if current <= 0 { return nil }
            defer { current -= 1 }
            return current
          }
        }
      }
      
      for number in CountDown(start: 3) {
        print(number)
      }
      What is the output?
      medium
      A. 3 2 1 0
      B. 3 2 1
      C. 4 3 2 1
      D. 1 2 3

      Solution

      1. Step 1: Understand the iterator logic

        The iterator starts at start (3). It returns current if > 0, then decreases current by 1 after returning.
      2. Step 2: Trace the iteration values

        First call returns 3, then current becomes 2. Next returns 2, current becomes 1. Next returns 1, current becomes 0. Next call returns nil because current is 0, ending iteration.
      3. Final Answer:

        3 2 1 -> Option B
      4. Quick Check:

        CountDown from 3 to 1 = 3 2 1 [OK]
      Hint: Check when next() returns nil to find iteration end [OK]
      Common Mistakes:
      • Including 0 in output though iteration stops before
      • Assuming count goes up instead of down
      • Misreading defer behavior
      4. This code attempts to create a custom sequence but has an error:
      struct MySequence: Sequence {
        func makeIterator() -> MyIterator {
          return MyIterator()
        }
      }
      
      struct MyIterator: IteratorProtocol {
        var count = 3
        func next() -> Int? {
          if count == 0 { return nil }
          count -= 1
          return count
        }
      }
      What is the main problem here?
      medium
      A. next() is a func but modifies count, which is a struct property
      B. makeIterator() should return IteratorProtocol instead of MyIterator
      C. count should start at 0, not 3
      D. next() must return non-optional Int

      Solution

      1. Step 1: Identify mutability issue in next()

        The next() method tries to change count, but it is declared in a struct and next() is not marked mutating.
      2. Step 2: Understand Swift struct rules

        In structs, methods that modify properties must be marked mutating. Without it, the compiler will error.
      3. Final Answer:

        next() is a func but modifies count, which is a struct property -> Option A
      4. Quick Check:

        Mutating methods must be marked mutating = A [OK]
      Hint: Mark methods mutating if they change struct properties [OK]
      Common Mistakes:
      • Forgetting mutating keyword on next()
      • Thinking return type must be non-optional
      • Confusing return type with protocol requirement
      5. You want to create a custom sequence that iterates over only even numbers from 2 up to a given limit. Which implementation correctly uses the Sequence protocol for this?
      hard
      A. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { while current <= limit { let result = current current += 2 return result } return nil } } }
      B. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 0 return AnyIterator { current += 2 if current < limit { return current } return nil } } }
      C. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { if current <= limit { let result = current current += 2 return result } return nil } } }
      D. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 0 return AnyIterator { if current < limit { current += 2 return current } return nil } } }

      Solution

      1. Step 1: Check iterator logic for even numbers

        The iterator should start at 2 and return current if <= limit, then add 2 for next call.
      2. Step 2: Analyze each option's iteration behavior

        struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { while current <= limit { let result = current current += 2 return result } return nil } } } uses a while loop inside the closure, which causes it to return only once and then exit, so it won't iterate properly. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { if current <= limit { let result = current current += 2 return result } return nil } } } uses an if check and returns current then increments, correctly producing even numbers up to limit. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 0 return AnyIterator { current += 2 if current < limit { return current } return nil } } } increments before checking, so first returned number is 2, which is correct, but starts at 0 which is okay. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 0 return AnyIterator { if current < limit { current += 2 return current } return nil } } } increments after checking current < limit, so it may skip the limit if limit is even. struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { if current <= limit { let result = current current += 2 return result } return nil } } } is the clearest and correct implementation.
      3. Final Answer:

        struct EvenNumbers: Sequence { let limit: Int func makeIterator() -> AnyIterator<Int> { var current = 2 return AnyIterator { if current <= limit { let result = current current += 2 return result } return nil } } } -> Option C
      4. Quick Check:

        Use if check and increment after return for correct iteration = B [OK]
      Hint: Use if condition inside iterator closure, not while loop [OK]
      Common Mistakes:
      • Using while loop inside iterator closure causing single return
      • Incrementing before returning causing off-by-one errors
      • Incorrect start value causing wrong first element
      Recommended

      Ready to prove it?

      Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

      10 questions~5 mineasy hard