Skip to content

Instantly share code, notes, and snippets.

@dkulundzic
Last active February 2, 2023 12:47
Show Gist options
  • Save dkulundzic/ee13d6f15245bbcd7b7cec5b04a8c1cc to your computer and use it in GitHub Desktop.
Save dkulundzic/ee13d6f15245bbcd7b7cec5b04a8c1cc to your computer and use it in GitHub Desktop.
An example "smart" Collection with embedded filtering abilities
public struct FilteringList<Element, Filter>: Collection {
public typealias Filtering = (Element, Filter?) -> Bool
public typealias Index = Int
public typealias Element = Element
public var filtering: Filtering? {
didSet { filter(using: selectedFilter) }
}
public var selectedFilter: Filter? {
didSet { filter(using: selectedFilter) }
}
public var elements = [Element]() {
didSet { filter(using: selectedFilter) }
}
private var filteredElements = [Element]()
public init(
_ elements: [Element] = [],
filtering: Filtering? = nil
) {
self.elements = elements
self.filtering = filtering
}
}
public extension FilteringList {
var output: [Element] {
return selectedFilter == nil ? elements: filteredElements
}
}
// MARK: - Collection
public extension FilteringList {
subscript(position: Int) -> Element {
return filteredElements[position]
}
var startIndex: Int {
return filteredElements.startIndex
}
var endIndex: Int {
return filteredElements.endIndex
}
func index(after index: Int) -> Int {
return filteredElements.index(after: index)
}
}
// MARK: - ExpressibleByArrayLiteral
extension FilteringList: ExpressibleByArrayLiteral {
public init(arrayLiteral elements: Element...) {
self.elements = elements
}
public typealias ArrayLiteralElement = Element
}
// MARK: - Private
private extension FilteringList {
mutating func filter(using selectedFilter: Filter?) {
guard let filtering = self.filtering else {
filteredElements = elements
return SimpleLogger.warning("The filtering closure has not been set. Returning unfiltered elements...")
}
filteredElements = elements.filter { element -> Bool in
return filtering(element, selectedFilter)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment