Iterator pattern은 여러 타입에 access를 가능하게 해주는 공통된 인터페이스를 제공한다.
protocol Iterator {
mutating func nextVal() -> Any?
func hasNext() -> Bool
}
Array, Tree, Hash, Set등 컨테이너의 타입과 관계없이 Iterator의 인터페이스만 가지고 같은 알고리즘을 적용시킬 수 있다!
protocol Iterator {
mutating func nextVal() -> Any?
func hasNext() -> Bool
}
class ArrayIterator: Iterator {
private var container: [Any]
private var pos: Int
init(arrayContainer: ArrayContainer) {
self.container = arrayContainer.container
self.pos = -1
}
func hasNext() -> Bool {
return pos < container.count - 1
}
mutating func nextVal() -> Any? {
if hasNext() {
pos += 1
return container[pos]
}
return nil
}
}
class ArrayContainer {
var container: [Any]
init(container: [Any]) {
self.container = container
}
}
protocol Iterator {
mutating func nextVal() -> Any?
func hasNext() -> Bool
}
class ArrayRevIterator: Iterator {
private var container: [Any]
private var pos: Int
init(arrayContainer: ArrayContainer) {
self.container = arrayContainer.container
self.pos = container.count
}
func hasNext() -> Bool {
return pos > 0
}
mutating func nextVal() -> Any? {
if hasNext() {
pos -= 1
return container[pos]
}
return nil
}
}
class ArrayContainer {
var container: [Any]
init(container: [Any]) {
self.container = container
}
}
다음 칸을 가리키는 알고리즘을 프로토콜과 arrayContainer의 조합으로 위와 같이 구현할 수 있다
Whenever you use a for-in loop with an array, set, or any other collection or sequence, you’re using that type’s iterator. Swift uses a sequence’s or collection’s iterator internally to enable the for-in loop language construct.
//단순한 For문
let animals = ["Antelope", "Butterfly", "Camel", "Dolphin"]
for animal in animals {
print(animal)
}
// Prints "Antelope"
// Prints "Butterfly"
// Prints "Camel"
// Prints "Dolphin"
//Iterator 프로토콜 사용
var animalIterator = animals.makeIterator()
while let animal = animalIterator.next() {
print(animal)
}
// Prints "Antelope"
// Prints "Butterfly"
// Prints "Camel"
// Prints "Dolphin"
You can initialize the Countdown sequence with a starting integer and then iterate over the count down to zero. The Countdown structure’s definition is short: It contains only the starting count and the makeIterator() method required by the Sequence protocol.
struct Countdown: Sequence {
let start: Int
func makeIterator() -> CountdownIterator {
return CountdownIterator(self)
}
}
struct CountdownIterator: IteratorProtocol {
let countdown: Countdown
var times = 0
init(_ countdown: Countdown) {
self.countdown = countdown
}
mutating func next() -> Int? {
let nextNumber = countdown.start - times
guard nextNumber > 0
else { return nil }
times += 1
return nextNumber
}
}
let threeTwoOne = Countdown(start: 3)
for count in threeTwoOne {
print("\(count)...")
}
// Prints "3..."
// Prints "2..."
// Prints "1..."