Post

Replies

Boosts

Views

Activity

Reply to Swift Protocol Constraint Required - Advanced
here is my implementation (before swift 5.7) and I would like to do it with the new Any / Unboxing feature of Swift 5.7 the goal is to have a generic class FilterManager that accepts a generic array to be filtered and a list of filters, inside the init we loop on the filter fields and pass the array, each filter is then responsible to extract the values (remove duplicates) thanks public protocol ManagedFilter: AnyObject {     associatedtype ArrayType     typealias Condition = ((ArrayType) -> Bool)     var name: String { get }     var condition: Condition? { get }     func extractValues(from array: [ArrayType]) } public protocol FilterSpecification: ManagedFilter {     associatedtype ValueType: Comparable     var values: [ValueType] { get set } } // MARK: - Abstract Base private class _AnyFilterBase<ArrayType>: ManagedFilter {     init() {         guard type(of: self) != _AnyFilterBase.self else {             fatalError("_AnyFilterBase<ArrayType> instances can not be created; create a subclass instance instead")         }     }     var name: String { fatalError("Must override") }     var condition: Condition? {         fatalError("Must override")     }     func extractValues(from array: [ArrayType]) {         fatalError("Must override")     } } // MARK: - Private Box fileprivate class _AnyFilterBox<Base: ManagedFilter>: _AnyFilterBase<Base.ArrayType> {     var base: Base     init(_ base: Base) {         self.base = base     }     fileprivate override var name: String { base.name }     fileprivate override var condition: Condition? {         base.condition     }     fileprivate override func extractValues(from array: [Base.ArrayType]) {         base.extractValues(from: array)     } } // MARK: - Public Wrapper final public class AnyFilter<ArrayType>: ManagedFilter {     private let box: _AnyFilterBase<ArrayType>     public init<Base: ManagedFilter>(_ base: Base) where Base.ArrayType == ArrayType {         box = _AnyFilterBox(base)     }     public var name: String { box.name }     public var condition: ((ArrayType) -> Bool)? {         box.condition     }     public func extractValues(from array: [ArrayType]) {         box.extractValues(from: array)     } } public class FiltersManager1<T> {     private var originalArray: [T]     private var filteredArray: [T]     private(set) var filters: [AnyFilter<T>]     public init(array: [T], filters: [AnyFilter<T>]) {         self.originalArray = array         self.filteredArray = array         self.filters = filters         for filter in filters {             filter.extractValues(from: array)         }     } } struct City1 {     let code: String     let country: String     let region: String } class CountryFilter1: FilterSpecification {     var name = "Country"     var values = [String]()     var condition: ((City1) -> Bool)? {         guard !values.isEmpty else { return nil }         return { city in             self.values.contains(city.country)         }     }     func extractValues(from array: [City1]) {         // remove duplicates     } } class RegionFilter1: FilterSpecification {     var name = "Region"     var values = [String]()     var condition: ((City1) -> Bool)? {         guard !values.isEmpty else { return nil }         return { city in             self.values.contains(city.region)         }     }     func extractValues(from array: [City1]) {         // remove duplicates     } } let cities = [City1]() let manager = FiltersManager1(array: cities, filters: [AnyFilter(CountryFilter1()), AnyFilter(RegionFilter1())])
Nov ’22