Swift Sequences & Collections
-
Upload
cocoaheads-france -
Category
Software
-
view
5.485 -
download
0
Transcript of Swift Sequences & Collections
Swift Sequences & Collections
@greg3z
let array = [1, 2, 3]
let array = [1, 2, 3]
array[7] 😭
let dic = ["a": 1, "b": 2]
let dic = ["a": 1, "b": 2]
dic["z"] 😎
[] -> subscript
struct Array<Element> { subscript(index: Int) -> Element }
struct Dictionary<Key: Hashable, Value> { subscript(key: Key) -> Value? }
subscript(index: Int) -> Element?
subscript(safe index: Int) -> Element?
subscript(safe index: Int) -> Element?
array[safe: 2]
extension Array { subscript(safe i: Int) -> Element? { return i >= 0 && i < count ? self[i] : nil } }
let array = [1, 2, 3]
let array = [1, 2, 3]
array[safe: 7] 😎
Custom collection? A type that I did myself
struct Section<T> { let title: String let elements: [T] }
struct Section<T> { let title: String let elements: [T] subscript(index: Int) -> T? { return elements[safe: index] } }
let cars = ["911", "Cayman", "Cayenne"] let section = Section(title: "Porsche", elements: cars)
let cars = ["911", "Cayman", "Cayenne"] let section = Section(title: "Porsche", elements: cars)
section[1] // Optional("Cayman")
Sequence A type that can be iterated with a `for`...`in` loop
protocol SequenceType { func generate() -> GeneratorType }
protocol GeneratorType {
func next() -> Element? }
struct ArrayGenerator<T>: GeneratorType { func next() -> T? { return something } }
struct ArrayGenerator<T>: GeneratorType { let array: [T] var currentIndex = 0 init(_ array: [T]) { self.array = array } mutating func next() -> T? { return array[safe: currentIndex++] } }
struct Section<T>: SequenceType { let title: String let elements: [T] func generate() -> ArrayGenerator<T> { return ArrayGenerator(elements) } }
var generator = section.generate() while let element = generator.next() { }
for element in section { }
var generator = section.generate() while let element = generator.next() { }
for element in section { }
let cars = ["911", "Cayman", "Cayenne"] let section = Section(title: "Porsche", elements: cars)
for car in section {
} // 911 // Cayman // Cayenne
for (index, car) in section.enumerate() {
} // 0 911 // 1 Cayman // 2 Cayenne
section.minElement() // 911
section.maxElement() // Cayman
section.sort() // ["911", "Cayenne", "Cayman"]
section.contains("911") // true
section.filter { $0.characters.count > 3 } // ["Cayman", "Cayenne"]
section.map { $0.characters.count } // [3, 6, 7]
section.reduce(0) { $0 + $1.characters.count } // 16
Collection A multi-pass *sequence* with addressable positions
protocol CollectionType : Indexable, SequenceType { }
protocol Indexable { var startIndex: Index { get } var endIndex: Index { get } }
struct Section<T>: Indexable { let title: String var elements: [T] var startIndex: Int { return 0 } var endIndex: Int { return elements.count }
subscript(index: Int) -> T? { … } func generate() -> ArrayGenerator<T> { … }
}
protocol Indexable { var startIndex: Index { get } var endIndex: Index { get } subscript(position: Index) -> Element { get } }
struct Section<T>: CollectionType { let title: String var elements: [T] var startIndex: Int { return 0 } var endIndex: Int { return elements.count } subscript(index: Int) -> T? { … }
func generate() -> ArrayGenerator<T> { … } }
struct Section<T>: CollectionType { let title: String var elements: [T] var startIndex: Int { return 0 } var endIndex: Int { return elements.count } subscript(index: Int) -> T { return elements[index] }
func generate() -> ArrayGenerator<T> { … } }
struct Section<T>: CollectionType { let title: String let elements: [T] var startIndex: Int { return 0 } var endIndex: Int { return elements.count } subscript(index: Int) -> T { return elements[index] } subscript(safe index: Int) -> T? { return elements[safe: index] }
func generate() -> ArrayGenerator<T> { … } }
let cars = ["911", "Cayman", "Cayenne"] let section = Section(title: "Porsche", elements: cars)
section.count // 3
section.first // Optional("911")
section.isEmpty // false
section.indexOf("Cayman") // 1
Epilogue So dictionaries aren’t Collections?
struct Dictionary<K : Hashable, V> {
subscript(key: K) -> V? subscript(position: DictionaryIndex<K, V>) -> (K, V) }
let dic = ["a": "audi", "b": "bmw", "c": "citroen"]
let index = dic.startIndex // DictionaryIndex<String, String>
dic[index] // ("a", "audi")
dic[index.advancedBy(1)] // ("b", "bmw")
dic[index.advancedBy(3)] // Fatal error