Skip to content

Interactor and Collections

Posted on:March 23, 2017 at 03:28 PM

In this week, I watched this video named “Everything you ever wanted to know about Sequence & Collection” with Soroush Khanlou, in Skilled website. If you want to watch other great talks, this is a perfect website.

And I thought about this topic and small changes in your day-by-day in the development scene. I did a small exercise with this concepts and practice. My first exercise is a circular queue, an infinite queue.

class CircularQueue<T> : IteratorProtocol, RandomAccessCollection {
    typealias Element = T
    public typealias Index = Int
    public typealias Indices = CountableRange<Int>
    
        var position = 0
        let items : [T]
    
        init(items:[T]){
            self.items = items
        }
    
        func next() -> T? {
            let item = items[position]
            position = ((position + 1) % items.count)
            return item
        }
    
        public var startIndex: Int {
            return 0
        }
    
        public var endIndex: Int {
            return items.count
        }
    
        public func index(after i: Int) -> Int {
            _precondition(i == startIndex)
            return endIndex
        }
    
        public func index(before i: Int) -> Int {
            _precondition(i == endIndex)
            return startIndex
        }
    
        public subscript(position: Int) -> Element {
            get {
                let pos = (position % items.count)
                return items[pos]
            }
            set {
    
            }
        }
    }

In this sample, I create two strategies: First an interactor in a loop, where using function next to do this. Second, the developer pass an index and the calculate a correct position. Below has a sample using an UICollectionView to repeat the objects and the colors with the IndexPath Row.

import UIKit
import PlaygroundSupport

class CircularQueue<T> : IteratorProtocol, RandomAccessCollection {
    typealias Element = T
    public typealias Index = Int
    public typealias Indices = CountableRange<Int>

        var position = 0
        let items : [T]

        init(items:[T]){
            self.items = items
        }

        func next() -> T? {
            let item = items[position]
            position = ((position + 1) % items.count)
            return item
        }

        public var startIndex: Int {
            return 0
        }

        public var endIndex: Int {
            return items.count
        }

        public func index(after i: Int) -> Int {
            _precondition(i == startIndex)
            return endIndex
        }

        public func index(before i: Int) -> Int {
            _precondition(i == endIndex)
            return startIndex
        }

        public subscript(position: Int) -> Element {
            get {
                let pos = (position % items.count)
                return items[pos]
            }
            set {

            }
        }
    }

    class CollectionViewController : UICollectionViewController {

        let arrColor : [UIColor] = [.green,.yellow,.blue,.purple,.orange]

        override func viewDidLoad() {
            super.viewDidLoad()
            self.collectionView?.backgroundColor = .white
            self.collectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "PlayCell")
        }

        override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
            return 10000
        }

        override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "PlayCell", for: indexPath)
            let queue = CircularQueue(items: arrColor)
            cell.backgroundColor = queue[indexPath.row]
            return cell
        }

    }

    PlaygroundPage.current.liveView = CollectionViewController(collectionViewLayout: UICollectionViewFlowLayout())

Another small sample

In many moments, you need a Random Acess in an Array. It’s very common this problem. And I create a small sample to this:

class RandomQueue<T> : IteratorProtocol {
    typealias Element = T

    var position = 0
    var positions : [Int] = []
    let items : [T]

    init(items:[T]){
        self.items = items
    }

    func next() -> T? {
        guard positions.count != items.count else { return nil }
        return items[random()]
    }

    fileprivate func random() -> Int {
        var ranNumber : Int = 0
        repeat {
            ranNumber = Int(arc4random_uniform(UInt32(items.count)))
        } while (positions.contains(ranNumber))
        positions.append(ranNumber)
        return ranNumber
    }
}

Yes, this sample it’s very simple and fools, but the idea is to show what you can to do with this knowledge about Collections and Sequence.

Watch this talk and try!