Here's an example of how to sort the nil dates to the end of an array.
In the example, movies is an array of type Movie, which has a date property.
let sortedMovies = movies.sorted { (movieA, movieB) -> Bool in
switch (movieA.date, movieB.date) {
case (.some, .some):
return movieA.date! > movieB.date!
case (.some, .none):
return true
case (.none, _):
return false
}
}
Here are some extensions for this function, one non-mutating and one mutating, and with a parameter for descending/ascending.
extension Array
{
func propertySorted<T: Comparable>(_ property: (Element) -> T?, descending: Bool) -> [Element]
{
sorted(by: {
switch (property($0), property($1)) {
case (.some, .some):
return descending ? property($0)! > property($1)! : property($0)! < property($1)!
case (.some, .none):
return true
case (.none, _):
return false
}
})
}
mutating func propertySort<T: Comparable>(_ property: (Element) -> T?, descending: Bool)
{
sort(by: {
switch (property($0), property($1)) {
case (.some, .some):
return descending ? property($0)! > property($1)! : property($0)! < property($1)!
case (.some, .none):
return true
case (.none, _):
return false
}
})
}
}
Usage:
let movieNames = movies.propertySorted({ $0.name }, descending: false)
let movieDates = movies.propertySorted({ $0.date }, descending: true)
movies.propertySort({ $0.name }, descending: false)
movies.propertySort({ $0.date }, descending: true)
Extension assistance credit to @Sweeper for answer on Generic function to sort array of class by properties