Group Group Group Group Group Group Group Group Group

Iterator | raywenderlich.com


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/1941302-intermediate-ios-design-patterns/lessons/8

Hey, I get this error in playground.

List of tickets
Could not cast value of type 'Swift.Range<Swift.Int>' (0x7fff8734cbf8) to '__lldb_expr_10.Ticket' (0x10fa9b138).

And also for sorted as well.

public struct Queue<T> {
    private var array: [T?] = []
    private var head = 0
    
    public var count: Int {
        return array.count - head
    }
    
    public var isEmpty: Bool {
        return array.count == 0
    }
    
    public mutating func enqueue(_ element: T) {
        array.append(element)
    }
    
    public mutating func dequeue() -> T? {
        guard head < array.count,
              let element = array[head] else {
            return nil
            
        }
        array[head] = nil
        head += 1
        let percentage = Double(head)/Double(array.count)
        if array.count > 50, percentage > 0.25 {
            array.removeFirst(head)
            head = 0
        }
        return element
    }
}

public struct Ticket {
    enum PriorityType {
        case low
        case medium
        case high
    }
    
    var description: String
    var priority: PriorityType
}

extension Queue: Sequence {
    public func makeIterator() -> IndexingIterator<Array<T>> {
        let nonEmptyValues = Array([head  ..< array.count]) as! [T]
        return nonEmptyValues.makeIterator()
    }
}

extension Ticket {
    var sortIndex: Int {
        switch self.priority {
        case .low:      return 0
        case .medium:   return 1
        case .high:     return 2
        }
    }
}

var queue = Queue<Ticket>()
queue.enqueue(Ticket(description: "1", priority: .low))
queue.enqueue(Ticket(description: "3", priority: .medium))
queue.enqueue(Ticket(description: "4", priority: .high))
queue.enqueue(Ticket(description: "2", priority: .low))

print("List of tickets")
for ticket in queue {
    print(ticket.description)
}

var sortedTickets = queue.sorted {
    $0.sortIndex > $1.sortIndex
}

for ticket in sortedTickets {
    print(ticket.description)
}

The only question I got is why use complicated logic to clean the queue when dequeue() instead of simply
public mutating func dequeue() -> T? { guard array.count > 0 else { return nil } let element = array.first array.removeFirst() return element })
This also eliminates using ‘head’ variable.

Are there any benefits that I don’t see?

Thanks!

P.S. Sorry for posting code like this - I didn’t get how to format it correctly.