Skip to content

Instantly share code, notes, and snippets.

@nicholaslythall
Created September 7, 2020 23:08
Show Gist options
  • Save nicholaslythall/2a597328dd64b0c946d1c50082e91023 to your computer and use it in GitHub Desktop.
Save nicholaslythall/2a597328dd64b0c946d1c50082e91023 to your computer and use it in GitHub Desktop.
Swift property wrapper that ensures a wrapped array is always sorted, with convenience initializers for Comparable elements and sorting by a KeyPath
@propertyWrapper
struct Sorted<Value> {
var wrappedValue: [Value] {
didSet {
wrappedValue.sort(by: comparator)
}
}
typealias Comparator = (Value, Value) -> Bool
private let comparator: Comparator
init(wrappedValue: [Value] = [], comparator: @escaping Comparator) {
self.wrappedValue = wrappedValue.sorted(by: comparator)
self.comparator = comparator
}
}
extension Sorted: Equatable where Value: Equatable {
static func == (lhs: Sorted<Value>, rhs: Sorted<Value>) -> Bool {
return lhs.wrappedValue == rhs.wrappedValue
}
}
extension Sorted where Value: Comparable {
init(wrappedValue: [Value] = [], ascending: Bool = true) {
self.init(
wrappedValue: wrappedValue,
comparator: ascending ? { $0 < $1 } : { $0 > $1 }
)
}
}
extension Sorted {
init<C: Comparable>(wrappedValue: [Value] = [], by keyPath: KeyPath<Value, C>, ascending: Bool = true) {
self.init(
wrappedValue: wrappedValue,
comparator: ascending ? { $0[keyPath: keyPath] < $1[keyPath: keyPath] } : { $0[keyPath: keyPath] < $1[keyPath: keyPath] }
)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment