[행동패턴 ] Iterator pattern

suojae·2023년 12월 21일
0

[iOS] 디자인패턴

목록 보기
6/10

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의 조합으로 위와 같이 구현할 수 있다


Swift Iterator Interface

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..."
profile
Hi 👋🏻 I'm an iOS Developer who loves to read🤓

0개의 댓글