I am trying to pass a multiple tuples containing a KeyPath and a type of a sort order to a method that should do sorting.
I have this method:
extension Array {
mutating func sort<T: Comparable>(by criteria: (path: KeyPath<Element, T>, order:OrderType)...) {
criteria.forEach { path, order in
//...
sort { first, second in
order.makeComparator()(
first[keyPath: path],
second[keyPath: path]
)
}
}
}
}
and I am using it like this:
var posts = BlogPost.examples
posts.sort(by:(path:\.pageViews, order: .asc), (path:\.sessionDuration, order: .desc))
Now, cause both pageViews
and sessionDuration
properties are integers
, this will work.
But if I want to pass two properties of different types (say String
and Int
), I am getting this error:
Key path value type 'Int' cannot be converted to contextual type 'String'
Here is rest of the code, but I guess is not that relevant:
enum OrderType: String {
case asc
case desc
}
extension OrderType {
func makeComparator<T: Comparable>() -> (T, T) -> Bool {
switch self {
case .asc:
return (<)
case .desc:
return (>)
}
}
}
How should I define sort method so that I it accept heterogenous key paths?