Bird
Raised Fist0
Swiftprogramming~10 mins

Sequence protocol for custom iteration in Swift - Interactive Code Practice

Choose your learning style10 modes available
Practice - 5 Tasks
Answer the questions below
1fill in blank
easy

Complete the code to make the class conform to the Sequence protocol.

Swift
class Countdown: Sequence {
    let start: Int
    init(start: Int) {
        self.start = start
    }
    func makeIterator() -> [1] {
        return CountdownIterator(current: start)
    }
}

class CountdownIterator: IteratorProtocol {
    var current: Int
    init(current: Int) {
        self.current = current
    }
    func next() -> Int? {
        if current <= 0 {
            return nil
        } else {
            defer { current -= 1 }
            return current
        }
    }
}
Drag options to blanks, or click blank then click option'
AIteratorProtocol
BSequence
CCountdownIterator
DInt
Attempts:
3 left
💡 Hint
Common Mistakes
Returning the wrong type from makeIterator(), like Int or Sequence.
Forgetting to implement makeIterator() method.
2fill in blank
medium

Complete the code to use the custom sequence in a for-in loop.

Swift
let countdown = Countdown(start: 3)
for number in [1] {
    print(number)
}
Drag options to blanks, or click blank then click option'
Acountdown
BCountdownIterator()
CCountdown()
DCountdown.makeIterator()
Attempts:
3 left
💡 Hint
Common Mistakes
Trying to iterate over the iterator directly instead of the sequence.
Calling makeIterator() explicitly in the for-in loop.
3fill in blank
hard

Fix the error in the next() method to correctly stop iteration.

Swift
func next() -> Int? {
    if current [1] 0 {
        return nil
    } else {
        defer { current -= 1 }
        return current
    }
}
Drag options to blanks, or click blank then click option'
A<=
B==
C>=
D!=
Attempts:
3 left
💡 Hint
Common Mistakes
Using > or != causes the loop to never end or behave incorrectly.
Using == only stops at exactly zero, missing negative values.
4fill in blank
hard

Fill both blanks to create a dictionary comprehension that maps numbers to their squares for numbers greater than 2.

Swift
let squares = Dictionary(uniqueKeysWithValues: (3...6).map { number in
    (number, number [1] number) 
}).filter { $0.key [2] 2 }
Drag options to blanks, or click blank then click option'
A*
B>
C+
D<
Attempts:
3 left
💡 Hint
Common Mistakes
Using + instead of * for squaring.
Using < instead of > for filtering.
5fill in blank
hard

Fill all three blanks to create a dictionary from a sequence where keys are strings uppercased and values are filtered to be greater than zero.

Swift
let data = ["a": 1, "b": -1, "c": 3]
let filtered = data.reduce(into: [:]) { result, pair in
    let (key, value) = pair
    if value [1] 0 {
        result[[2]] = [3]
    }
}
Drag options to blanks, or click blank then click option'
A>
Bkey.uppercased()
Cvalue
D<
Attempts:
3 left
💡 Hint
Common Mistakes
Using < instead of > for filtering.
Using key instead of key.uppercased() for dictionary keys.
Assigning key instead of value to the dictionary.

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