Last active
August 20, 2020 10:32
-
-
Save jcampbell05/519c2f68629feb6db9b262449e97fba2 to your computer and use it in GitHub Desktop.
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
import UIKit | |
protocol Sortable {} | |
extension Sequence where Element: Sortable { | |
func sort(_ groups: [AnyComparableKeypath<Self.Element>]) -> [Self.Element] { | |
return self.sorted { | |
lhs, rhs in | |
for group in groups { | |
let result = group.compare(lhs, rhs) | |
switch result { | |
case .assending: | |
return true | |
case .decending: | |
return false | |
default: | |
break | |
} | |
} | |
return false | |
} | |
} | |
} | |
struct Person { | |
let firstName: String | |
let lastName: String | |
let age: Int | |
} | |
extension Person: Sortable {} | |
struct AnyComparableKeypath<E> { | |
enum GroupResult { | |
case same | |
case decending | |
case assending | |
} | |
init<T>(_ key: KeyPath<E, T>) where T: Comparable { | |
self.compare = { | |
lhs, rhs in | |
let firstItem = lhs[keyPath: key] | |
let secondItem = rhs[keyPath: key] | |
if firstItem < secondItem { | |
return .assending | |
} else if firstItem > secondItem { | |
return .decending | |
} | |
return .same | |
} | |
} | |
fileprivate let compare: (E, E) -> GroupResult | |
} | |
typealias _$ = AnyComparableKeypath | |
let people = [ | |
Person(firstName: "James", lastName: "Campbell", age: 4), | |
Person(firstName: "Bruce", lastName: "Wayne", age: 21), | |
Person(firstName: "Bruce", lastName: "Wayne", age: 5), | |
Person(firstName: "Bob", lastName: "Campbell", age: 18), | |
Person(firstName: "Bob", lastName: "Campbell", age: 8) | |
] | |
let sorted = people.sort([ | |
_$(\.firstName), | |
_$(\.lastName), | |
_$(\.age) | |
]) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment