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!