Last active
September 27, 2017 05:06
-
-
Save JohnEstropia/d0d3c59c715bb4e59b65e4ad3be5ea68 to your computer and use it in GitHub Desktop.
Collection that lazily initializes and caches its elements. Initially requires only the indexes and initializes elements as needed (e.g. UITableView data)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LazyCachedCollection.swift | |
// | |
// Created by John Estropia on 2017/09/27. | |
// Copyright © 2017 John Estropia. All rights reserved. | |
// | |
import Foundation | |
class LazyCachedCollection<Element>: RandomAccessCollection { | |
init(_ indices: CountableRange<Index>, _ initializer: @escaping (Index) -> Element) { | |
self.startIndex = indices.lowerBound | |
self.endIndex = indices.upperBound | |
var cache: [(Index, Element)] = [] | |
self.lazyEnumeration = indices.enumerated().lazy.map { (offset, index) -> (index: Index, element: Element) in | |
if offset < cache.endIndex { | |
return cache[offset] | |
} | |
let value = initializer(index) | |
let tuple: (index: Index, element: Element) = (index: index, element: value) | |
cache.append(tuple) | |
return tuple | |
} | |
} | |
// MARK: Sequence | |
typealias Iterator = AnyIterator<Element> | |
func makeIterator() -> Iterator { | |
var indexIterator = self.lazyEnumeration.makeIterator() | |
return AnyIterator { indexIterator.next()?.element } | |
} | |
// MARK: Collection | |
typealias Index = Int | |
let startIndex: Index | |
let endIndex: Index | |
subscript(position: Index) -> Iterator.Element { | |
return self.lazyEnumeration.first(where: { (index, _) in position == index })!.1 | |
} | |
func index(after i: Index) -> Index { | |
return self.indices.index(after: i) | |
} | |
// MARK: Private | |
private let lazyEnumeration: LazyMapSequence<EnumeratedSequence<CountableRange<Index>>, (index: Index, element: Element)> | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage:
Output