Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Everything You Ever Wanted To Know AboutSequence and Collection

Everything You Ever Wanted To Know AboutSequence and Collection

Soroush Khanlou

Playgrounds

March 04, 2017
Tweet

More Decks by Playgrounds

Other Decks in Programming

Transcript

  1. Everything You Ever Wanted To Know About Sequence and Collection

    Soroush Khanlou – 2017 – @khanlou Almost
  2. Sequence • List of elements • Can be finite or

    infinite • Iteration is not always repeatable
  3. LinkedList “A” value next end let a = ["A", "B",

    "C"] “B” value next “C” value next
  4. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } }
  5. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  6. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  7. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  8. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  9. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  10. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  11. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  12. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  13. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  14. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> ??? { return ??? } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  15. indirect enum LinkedListNode<T> { case value(element: T, next: LinkedListNode<T>) case

    end } extension LinkedListNode: Sequence { func makeIterator() -> LinkedListIterator<T> { return LinkedListIterator(current: self) } } struct LinkedListIterator<T>: IteratorProtocol { var current: LinkedListNode<T> mutating func next() -> T? { switch current { case let .value(element, next): current = next return element case .end: return nil } } }
  16. LinkedList “A” value next end let a = ["A", "B",

    "C"] “B” value next “C” value next
  17. LinkedList “A” value next end “A” value next “A” value

    next “A” value next end “B” value next “C” value next LinkedListIterator<String> current let iterator = LinkedListIterator<String>(current: linkedList) print(iterator.next()) // => “A”
  18. LinkedList “A” value next end “A” value next “A” value

    next “A” value next end “B” value next “C” value next LinkedListIterator<String> current let iterator = LinkedListIterator<String>(current: linkedList) print(iterator.next()) print(iterator.next()) // => “B”
  19. LinkedList “A” value next end “A” value next “A” value

    next “A” value next end “B” value next “C” value next LinkedListIterator<String> current let iterator = LinkedListIterator<String>(current: linkedList) print(iterator.next()) print(iterator.next()) print(iterator.next()) // => “C”
  20. LinkedList “A” value next end “A” value next “A” value

    next “A” value next end “B” value next “C” value next LinkedListIterator<String> current let iterator = LinkedListIterator<String>(current: linkedList) print(iterator.next()) print(iterator.next()) print(iterator.next()) print(iterator.next()) // => nil
  21. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great
  22. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  23. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  24. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  25. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  26. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  27. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  28. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  29. let numberOfAdmins = users.filter({ $0.isAdmin }).count // => fine let

    numberOfAdmins = users.count({ $0.isAdmin }) // => great extension Sequence { func count(_ shouldCount: (Iterator.Element) -> Bool) -> Int { var count = 0 for element in self { if shouldCount(element) { count += 1 } } return count } }
  30. extension Sequence { func eachPair() -> AnySequence<(Iterator.Element, Iterator.Element)> { return

    AnySequence(zip(self, self.dropFirst())) } } Argument type 'Self.SubSequence' does not conform to expected type 'Sequence'
  31. extension Sequence where Self.SubSequence: Sequence { func eachPair() -> AnySequence<(Iterator.Element,

    Iterator.Element)> { return AnySequence(zip(self, self.dropFirst())) } }
  32. extension Sequence where Self.SubSequence: Sequence { func eachPair() -> AnySequence<(Iterator.Element,

    Iterator.Element)> { return AnySequence(zip(self, self.dropFirst())) } } Cannot convert return expression of type 'AnySequence<(Self.Iterator.Element, Self.SubSequence.Iterator.Element)>' to return type 'AnySequence<(Self.Iterator.Element, Self.Iterator.Element)>'
  33. extension Sequence where Self.SubSequence: Sequence, Self.SubSequence.Iterator.Element == Self.Iterator.Element { func

    eachPair() -> AnySequence<(Iterator.Element, Iterator.Element)> { return AnySequence(zip(self, self.dropFirst())) } }
  34. Collection protocol Collection { associatedtype Index: Comparable var startIndex: Index

    var endIndex: Index subscript(position: Index) -> Iterator.Element { get } func index(after index: Index) -> Index }
  35. Collection protocol Collection { associatedtype Index: Comparable var startIndex: Index

    var endIndex: Index subscript(position: Index) -> Iterator.Element { get } func index(after index: Index) -> Index }
  36. Collection protocol Collection { associatedtype Index: Comparable var startIndex: Index

    var endIndex: Index subscript(position: Index) -> Iterator.Element { get } func index(after index: Index) -> Index }
  37. Collection protocol Collection { associatedtype Index: Comparable var startIndex: Index

    var endIndex: Index subscript(position: Index) -> Iterator.Element { get } func index(after index: Index) -> Index }
  38. func forEach(_ block: (Element) -> Void) { var currentIndex =

    self.startIndex while currentIndex < self.endIndex { block(self[currentIndex]) currentIndex = self.index(after: currentIndex) } }
  39. func forEach(_ block: (Element) -> Void) { var currentIndex =

    self.startIndex while currentIndex < self.endIndex { block(self[currentIndex]) currentIndex = self.index(after: currentIndex) } }
  40. func forEach(_ block: (Element) -> Void) { var currentIndex =

    self.startIndex while currentIndex < self.endIndex { block(self[currentIndex]) currentIndex = self.index(after: currentIndex) } }
  41. func forEach(_ block: (Element) -> Void) { var currentIndex =

    self.startIndex while currentIndex < self.endIndex { block(self[currentIndex]) currentIndex = self.index(after: currentIndex) } }
  42. func forEach(_ block: (Element) -> Void) { var currentIndex =

    self.startIndex while currentIndex < self.endIndex { block(self[currentIndex]) currentIndex = self.index(after: currentIndex) } }
  43. extension APIErrorCollection: Collection { var startIndex: Int { return _errors.startIndex

    } var endIndex: Int { return _errors.endIndex } func index(after index: Int) -> Int { return _errors.index(after: index) } subscript(position: Int) -> APIError { return _errors[position] } }
  44. extension APIErrorCollection: Collection { var startIndex: Int { return _errors.startIndex

    } var endIndex: Int { return _errors.endIndex } func index(after index: Int) -> Int { return _errors.index(after: index) } subscript(position: Int) -> APIError { return _errors[position] } }
  45. extension APIErrorCollection: Collection { var startIndex: Int { return _errors.startIndex

    } var endIndex: Int { return _errors.endIndex } func index(after index: Int) -> Int { return _errors.index(after: index) } subscript(position: Int) -> APIError { return _errors[position] } }
  46. extension APIErrorCollection: Collection { var startIndex: Int { return _errors.startIndex

    } var endIndex: Int { return _errors.endIndex } func index(after index: Int) -> Int { return _errors.index(after: index) } subscript(position: Int) -> APIError { return _errors[position] } }
  47. extension APIErrorCollection: Collection { var startIndex: Int { return _errors.startIndex

    } var endIndex: Int { return _errors.endIndex } func index(after index: Int) -> Int { return _errors.index(after: index) } subscript(position: Int) -> APIError { return _errors[position] } }
  48. struct APIErrorCollection { fileprivate let _errors: [APIError] } extension APIErrorCollection:

    Collection { // ... } errorCollection.contains({ $0.id == "error.item_already_added" }) // compiles!
  49. BidirectionalCollection protocol Collection { //... func index(after index: Index) ->

    Index } protocol BidirectionalCollection: Collection { func index(before index: Index) -> Index }
  50. BidirectionalCollection protocol Collection { //... func index(after index: Index) ->

    Index } protocol BidirectionalCollection: Collection { func index(before index: Index) -> Index }
  51. BidirectionalCollection var last: Iterator.Element? { guard !self.isEmpty else { return

    nil } let indexOfLastItem = self.index(before: self.endIndex) return self[indexOfLastItem] }
  52. BidirectionalCollection var last: Iterator.Element? { guard !self.isEmpty else { return

    nil } let indexOfLastItem = self.index(before: self.endIndex) return self[indexOfLastItem] }
  53. BidirectionalCollection var last: Iterator.Element? { guard !self.isEmpty else { return

    nil } let indexOfLastItem = self.index(before: self.endIndex) return self[indexOfLastItem] }
  54. BidirectionalCollection var last: Iterator.Element? { guard !self.isEmpty else { return

    nil } let indexOfLastItem = self.index(before: self.endIndex) return self[indexOfLastItem] }
  55. BidirectionalCollection extension BidirectionalCollection { func reversed() -> [Iterator.Element] { var

    elements: [Iterator.Element] = [] var currentIndex = self.endIndex while currentIndex > self.startIndex { currentIndex = self.index(before: currentIndex) elements.append(self[currentIndex]) } return elements } }
  56. BidirectionalCollection extension BidirectionalCollection { func reversed() -> [Iterator.Element] { var

    elements: [Iterator.Element] = [] var currentIndex = self.endIndex while currentIndex > self.startIndex { currentIndex = self.index(before: currentIndex) elements.append(self[currentIndex]) } return elements } }
  57. BidirectionalCollection extension BidirectionalCollection { func reversed() -> [Iterator.Element] { var

    elements: [Iterator.Element] = [] var currentIndex = self.endIndex while currentIndex > self.startIndex { currentIndex = self.index(before: currentIndex) elements.append(self[currentIndex]) } return elements } }
  58. BidirectionalCollection extension BidirectionalCollection { func reversed() -> [Iterator.Element] { var

    elements: [Iterator.Element] = [] var currentIndex = self.endIndex while currentIndex > self.startIndex { currentIndex = self.index(before: currentIndex) elements.append(self[currentIndex]) } return elements } }
  59. BidirectionalCollection extension BidirectionalCollection { func reversed() -> [Iterator.Element] { var

    elements: [Iterator.Element] = [] var currentIndex = self.endIndex while currentIndex > self.startIndex { currentIndex = self.index(before: currentIndex) elements.append(self[currentIndex]) } return elements } }
  60. RandomAccessCollection • Contant-time (O(1)) access to all elements • No

    new implementation requirements, only new semantics
  61. RandomAccessCollection func index(_ i: Self.Index, offsetBy n: Self.IndexDistance) -> Self.Index

    func distance(from start: Self.Index, to end: Self.Index) -> Self.IndexDistance
  62. Strideable protocol Strideable: Comparable { func advanced(by n: Self.Stride) ->

    Self func distance(to other: Self) -> Self.Stride }