SE-0249 introduced the ability to use the key path expression \Root.value
wherever functions of (Root) -> Value
are allowed.
This is pretty awesome and now well used across projects.
What I'm trying to propose here is to add some new operators for key paths to make it easier to use it when trying to apply any logic to it.
Here is a couple of examples:
Let's say we would like to filter a dictionary and get all values that are true.
We can do this pretty easily with key path now by doing:
let dict = ["a": true, "b": true, "c": false]
let filtered = dict.filter(\.value) // returns ["a": true, "b": true]
Pretty cool but what if we want to filter the dictionary for false values?
Well now we can't use key path and we need to rely to the closure:
let filtered = dict.filter { !$0.value } // returns ["c": false]
The proposal here is to add the following operators:
prefix func !<V>(keyPath: KeyPath<V, Bool>) -> (V) -> Bool {
{ !$0[keyPath: keyPath]}
}
func ==<T, V: Equatable>(lhs: KeyPath<T, V>, rhs: V) -> (T) -> Bool {
return { $0[keyPath: lhs] == rhs }
}
func !=<T, V: Equatable>(lhs: KeyPath<T, V>, rhs: V) -> (T) -> Bool {
return { $0[keyPath: lhs] != rhs }
}
This would give us the ability to use key path as following:
let dict = ["a": true, "b": true, "c": false]
let filtered = dict.filter(!\.value)
let filtered2 = dict.filter(\.value == false)
Would appreciate any input here!