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

iOS Dev Meetup. Emelyanov Georgij - Collections...

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →

iOS Dev Meetup. Emelyanov Georgij - Collectionsunderhood

Avatar for Georgij Emelyanov

Georgij Emelyanov

April 12, 2019

Other Decks in Technology

Transcript

  1. COLLECTIONSUNDERHOOD Array Set Dictionary String Range AnyCollection EmptyCollection FlattenCollection ClosedRange

    LazyCollection ContiguousArray ArraySlice 2 Slice CollectionOfOne LazyMapCollection ReversedCollection
  2. A sequence is a list of values that you can

    step through one at a time. A type that provides sequential, iterated access to its elements Apple’s Doc COLLECTIONSUNDERHOOD Sequence 6
  3. COLLECTIONSUNDERHOOD let confs = [...] for conf in confs {

    print(conf) } // Behind the scenes var iterator = confs.makeIterator() while let conf = iterator.next() { print(conf) } 7
  4. COLLECTIONSUNDERHOOD IteratorProtocol mutating func next() -> Elements.Element? { if _position

    == _elements.endIndex { return nil } let element = _elements[_position] _elements.formIndex(after: &_position) return element } 10
  5. COLLECTIONSUNDERHOOD func filter(_:) func forEach(_:) func map(_:) func compactMap(_:) func

    contains(_:) func dropFirst(_:) func dropLast(_:) func prefix(_:) func suffix(_:) ... Sequence 11
  6. COLLECTIONSUNDERHOOD func count(where condition: (Element) throws -> Bool) rethrows ->

    Int { var count = 0 for element in self where try condition(element) { count += 1 } return count } Sequence 12
  7. In addition to the operations that collections inherit from the

    Sequence protocol, you gain access to methods that depend on accessing an element at a specific position in a collection. Apple’s Doc COLLECTIONSUNDERHOOD Collection 13
  8. COLLECTIONSUNDERHOOD var count: Int var endIndex: Self.Index var first: Self.Element?

    var indices: Self.Indices var isEmpty: Bool var startIndex: Self.Index subscript(_: Self.Index) subscript(_: Range<Self.Index>) ... Collection 14
  9. COLLECTIONSUNDERHOOD let products: [Category : [Product]] = [ .dairy: [

    Product(name: "Milk", category: .dairy), Product(name: "Butter", category: .dairy) ], .vegetables: [ Product(name: "Cucumber", category: .vegetables), Product(name: "Lettuce", category: .vegetables) ], ... ] 15
  10. COLLECTIONSUNDERHOOD func add(_ product: Product) { if var productsInCategory =

    products[product.category] { productsInCategory.append(product) products[product.category] = productsInCategory } else { products[product.category] = [product] } } 16
  11. COLLECTIONSUNDERHOOD if let dairyProducts = products[.dairy] { guard !dairyProducts.isEmpty else

    { renderEmptyView() return } render(dairyProducts) } else { renderEmptyView() } 17
  12. COLLECTIONSUNDERHOOD struct ProductCollection { typealias DictionaryType = [Category : [Product]]

    private var products = DictionaryType() init(products: DictionaryType) { self.products = products } } 18
  13. COLLECTIONSUNDERHOOD extension ProductCollection: Collection { var startIndex: Index { return

    products.startIndex } var endIndex: Index { return products.endIndex } subscript(index: Index) -> Iterator.Element { get { return products[index] } } func index(after i: Index) -> Index { return products.index(after: i) } } 19
  14. COLLECTIONSUNDERHOOD subscript(category: Category) -> [Product] { get { return products[category]

    ?? [] } set { products[category] = newValue } } 22 mutating func insert(_ product: Product) { var productsInCategory = self[product.category] productsInCategory.append(product) self[product.category] = productsInCategory }
  15. COLLECTIONSUNDERHOOD class MyClass { let value1: Int = 1 let

    value2: Int = 2 } let myClass = MyClass() print(myClass) (lldb) po myClass Demo.MyClass <MyClass: 0x6000023eeda0> 24
  16. COLLECTIONSUNDERHOOD protocol CustomStringConvertible { var description: String { get }

    } protocol CustomDebugStringConvertible { var debugDescription: String { get } } 25
  17. COLLECTIONSUNDERHOOD extension MyClass: CustomStringConvertible { var description: String { return

    "\(value1) & \(value2)" } } extension MyClass: CustomDebugStringConvertible { var debugDescription: String { return "debug \(value1) & \(value2)" } } 26
  18. COLLECTIONSUNDERHOOD let myClasses = [myClass1, myClass2, myClass3] ▿ 3 elements

    ▿ 0 : debug 1 & 2 ▿ 1 : debug 1 & 2 ▿ 2 : debug 1 & 2 29 [debug 1 & 2, debug 1 & 2, debug 1 & 2] print(myClasses) (lldb) po myClasses
  19. COLLECTIONSUNDERHOOD 31 var result = "" if let type =

    type { result += "\(type)([" } else { result += "[" }
  20. COLLECTIONSUNDERHOOD var first = true for item in self {

    if first { first = false } else { result += ", " } debugPrint(item, terminator: "", to: &result) } 32
  21. COLLECTIONSUNDERHOOD 36 func reset() { let mirror = Mirror(reflecting: self)

    for child in mirror.children { if let purgeable = child.value as? Purgeable { purgeable.purge() } } }
  22. COLLECTIONSUNDERHOOD Dictionary 40 Sequence Dictionary Collection Equatable Decodable Encodable Hashable

    CustomDebugStringConvertible CustomReflectable CustomStringConvertible ExpressibleByDictionaryLiteral
  23. COLLECTIONSUNDERHOOD Native Storage class __RawDictionaryStorage <isa> <refcount> _count _capacity _scale

    _age _seed _rawKeys _rawValue [inline bitset of occupied entries] [inline array of keys] [inline array of values] struct Dictionary<K, V> enum Dictionary<K, V>._Variant struct _NativeDictionary<K, V> 42
  24. COLLECTIONSUNDERHOOD Cocoa Storage class NSDictionary [refcount] … struct __CocoaDictionary.Index allKeys

    currentKeyIndex struct Dictionary<K, V> enum Dictionary<K, V>._Variant struct __CocoaDictionary 43
  25. COLLECTIONSUNDERHOOD Big O notation ▸ NSDictionary to Dictionary<NSObject, AnyObject> —

    O(1) ▸ NSDictionary to Dictionary<AnyHashable, AnyObject> — O(n) ▸ Dictionary<K, V> to NSDictionary — O(1) 44
  26. COLLECTIONSUNDERHOOD Set ▸ Two storage schemes ▸ Native ▸ Cocoa

    ▸ _HashTable ▸ ExpressibleByArrayLiteral ▸ SetAlgebra 45
  27. COLLECTIONSUNDERHOOD Set 46 Sequence Set Collection Equatable Decodable Encodable Hashable

    CustomDebugStringConvertible CustomReflectable CustomStringConvertible ExpressibleByArrayLiteral SetAlgebra
  28. COLLECTIONSUNDERHOOD mutating func formIntersection(_:) mutating func formSymmetricDifference(_:) mutating func formUnion(_:)

    mutating func subtract(_:) func intersection(_:) func subtracting(_:) func symmetricDifference(_:) func union(_:) ... SetAlgebra 47
  29. COLLECTIONSUNDERHOOD ArrayType 49 ExpressibleByArrayLiteral Sequence Array Collection Equatable Decodable Encodable

    Hashable CustomDebugStringConvertible CustomReflectable CustomStringConvertible RandomAccessCollection BidirectionalCollection RangeReplaceableCollection MutableCollection
  30. A collection that supports backward as well as forward traversal.

    Apple’s Doc COLLECTIONSUNDERHOOD BidirectionalCollection 50
  31. COLLECTIONSUNDERHOOD func index(before i: Index) -> Index func formIndex(before i:

    inout Index) mutating func removeLast(_ k: Int) mutating func removeLast() -> Element mutating func popLast() -> Element? ... BidirectionalCollection 51
  32. COLLECTIONSUNDERHOOD mutating func removeLast() -> Element { let element =

    last! self = self[startIndex..<index(before: endIndex)] return element } BidirectionalCollection 52
  33. COLLECTIONSUNDERHOOD typealias A = ArraySlice<Bool> func sieveOfEratosthenes(limit: Int) -> [Int]

    { var possibles = A(repeating: true, count: limit + 1) var result = [Int]() for i in 2 ... limit { guard possibles[i] else { continue } for j in stride(from: i * i, through: limit, by: i) { possibles[j] = false } result.append(i) } return result } 60
  34. COLLECTIONSUNDERHOOD Conclusion 64 ▸ Collections > 5 ▸ Use Swift’s

    protocols ▸ Dictionary, Set, ArrayType ▸ Array is slow ▸ NSPointerArray, NSMapTable, NSHashTable