Created
June 7, 2018 18:49
-
-
Save vhart/7ce9ac7d2ed10d8be9567614c328b7a4 to your computer and use it in GitHub Desktop.
Writing Filters Using KeyPaths
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
struct Filter<Object> { | |
let path: PartialKeyPath<Object> | |
let matcher: (Any) -> Bool | |
init<Type>(keyPath: KeyPath<Object, Type>, matcher: @escaping (Type) -> Bool) { | |
self.path = keyPath | |
self.matcher = { value in | |
guard let typedValue = value as? Type else { return false } | |
return matcher(typedValue) | |
} | |
} | |
func matches(_ value: Any) -> Bool { | |
return matcher(value) | |
} | |
} | |
class MyClass { | |
let name: String | |
let number: Int | |
let someBool: Bool | |
init(name: String, number: Int, bool: Bool) { | |
self.name = name | |
self.number = number | |
self.someBool = bool | |
} | |
} | |
let filters: [Filter<MyClass>] = [ | |
Filter(keyPath: \MyClass.name, matcher: { value in value == "hello"}), | |
Filter(keyPath: \MyClass.number, matcher: { value in value == 3 }), | |
Filter(keyPath: \MyClass.someBool, matcher: { value in value == true }) | |
] | |
func object<T>(_ object: T, matches filters: [Filter<T>]) -> Bool { | |
for filter in filters { | |
guard filter.matches(object[keyPath: filter.path]) else { return false } | |
} | |
return true | |
} | |
let obj1 = MyClass(name: "yo", number: 3, bool: false) | |
let obj2 = MyClass(name: "hello", number: 3, bool: true) | |
print(object(obj1, matches: filters)) | |
print(object(obj2, matches: filters)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment