Skip to content

Instantly share code, notes, and snippets.

@StanDimitroff
Last active April 23, 2018 14:11
Show Gist options
  • Save StanDimitroff/4fba1d80bc8d59f99ed2556fd3b7401c to your computer and use it in GitHub Desktop.
Save StanDimitroff/4fba1d80bc8d59f99ed2556fd3b7401c to your computer and use it in GitHub Desktop.
typealias SortDescriptor<Value> = (Value, Value) -> Bool
protocol Sortable: class {
var sortRules: [SortRule] { get }
var currentRule: SortRule { get }
func sortData()
}
extension Sortable {
func sortDescriptor<Value, Key>(key: @escaping (Value) -> Key, type: SortType)
-> SortDescriptor<Value>
where Key: Comparable {
switch type {
case .ascending: return { key($0) < key($1) }
case .descending: return { key($0) > key($1) }
default: return { key($0) == key($1) }
}
}
}
enum SortProperty {
case string(String)
case date(Date)
case bool(Bool)
}
enum SortType {
case ascending, descending, same
}
enum SortKey {
case name, date, status
}
extension SortProperty: Comparable {
static func <(lhs: SortProperty, rhs: SortProperty) -> Bool {
switch (lhs, rhs) {
case let (.string(text1), .string(text2)):
return text1.lowercased() < text2.lowercased()
case let (.date(date1), .date(date2)):
return date1 < date2
case let (.bool(bool1), .bool(bool2)):
return bool1 || bool2
default: return false
}
}
static func ==(lhs: SortProperty, rhs: SortProperty) -> Bool {
switch (lhs, rhs) {
case let (.string(text1), .string(text2)):
return text1 == text2
case let (.date(date1), .date(date2)):
return date1 == date2
default: return false
}
}
}
protocol Filterable {
var filterKey: String { get }
}
protocol Orderable {
var orderKey: String { get }
func sortProperty(by key: SortKey) -> SortProperty
}
protocol ListManagerData: Orderable {
var id: Int { get }
}
protocol ListManager: Sortable {
var data: [ListManagerData] { get set }
}
extension ListManager where Self: Sortable {
func sortData() {
let descriptor: SortDescriptor<Orderable> = sortDescriptor(
key: { $0.sortProperty(by: self.currentRule.key) },
type: self.currentRule.type)
data.sort(by: descriptor)
}
}
struct User: ListManagerData {
var id: Int = 0
var orderKey: String {
return self.name
}
func sortProperty(by key: SortKey) -> SortProperty {
switch key {
case .name: return .string(name)
case .date: return .date(dateCreated.dateFromString(sourceDateFormat: ApiDateTimeFormat))
default: fatalError(Errors.invalidType)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment