KeyPath works also on structs.
public struct MyStruct: Codable {
var urlPath: String
var bytes: Double
init(_ path: String,_ bytes: Double) {
self.urlPath = path
self.bytes = bytes
}
private enum CodingKeys: String, CodingKey {
case urlPath = "url_path"
case bytes = "bytes"
}
}
extension MyStruct: CustomStringConvertible {
public var description: String {
return "urlPath=\(urlPath),bytes=\(bytes)"
}
}
class MyClass {
var array: [MyStruct] = []
func sortArray<SortKeyType: Comparable>(descending: Bool, key: KeyPath<MyStruct, SortKeyType>) {
if descending {
self.array.sort(by: { $0[keyPath: key] > $1[keyPath: key] })
} else {
self.array.sort(by: { $0[keyPath: key] < $1[keyPath: key] })
}
}
////to write an example...
init(_ elements: (path: String, bytes: Double)...) {
self.array = elements.map(MyStruct.init)
}
//...
}
Example:
let myObj = MyClass(
("/A", 3),
("/B", 1),
("/C", 2)
)
myObj.sortArray(descending: false, key: \.urlPath)
print(myObj.array) //->[urlPath=/A,bytes=3.0, urlPath=/B,bytes=1.0, urlPath=/C,bytes=2.0]
myObj.sortArray(descending: true, key: \.bytes)
print(myObj.array) //->[urlPath=/A,bytes=3.0, urlPath=/C,bytes=2.0, urlPath=/B,bytes=1.0]
You can write a simple extension for Array, if you prefer.
extension Array {
mutating func sort<SortKeyType: Comparable>(descending: Bool = false, key: KeyPath<Element, SortKeyType>) {
if descending {
self.sort {$0[keyPath: key] > $1[keyPath: key]}
} else {
self.sort {$0[keyPath: key] < $1[keyPath: key]}
}
}
}
extension Array {
mutating func sort<SortKeyType: Comparable>(descending: Bool = false, key: KeyPath<Element, SortKeyType>) {
if descending {
self.sort {$0[keyPath: key] > $1[keyPath: key]}
} else {
self.sort {$0[keyPath: key] < $1[keyPath: key]}
}
}
}
var myArray = [
MyStruct("/A", 3),
MyStruct ("/B", 1),
MyStruct("/C", 2)
]
myArray.sort(key: \.bytes)
print(myArray) //->[urlPath=/B,bytes=1.0, urlPath=/C,bytes=2.0, urlPath=/A,bytes=3.0]