This has been asked and answered before using NSSortDescriptor
where it is quite easy. But is there a Swift-standard way using Array.sort()
?
struct Sortable {
let isPriority: Bool
let ordering: Int
}
Sorting an array of Sortables
by one property is simple:
sort { 0ドル.ordering < 1ドル.ordering }
But I want to sort by isPriority
then by ordering
- and I can't get my head around a simple statement to make that happen.
-
Should we close this question as a dupe, and point to this more popular variant of it? stackoverflow.com/q/37603960/3141234Alexander– Alexander2023年09月27日 17:17:37 +00:00Commented Sep 27, 2023 at 17:17
4 Answers 4
Yes there is a very simple way using the Array.sort()
Code:
var sorted = array.sorted({ (s1, s2) -> Bool in
if s1.isPriority && !s2.isPriority {
return true //this will return true: s1 is priority, s2 is not
}
if !s1.isPriority && s2.isPriority {
return false //this will return false: s2 is priority, s1 is not
}
if s1.isPriority == s2.isPriority {
return s1.ordering < s2.ordering //if both save the same priority, then return depending on the ordering value
}
return false
})
The sorted array:
true - 10
true - 10
true - 12
true - 12
true - 19
true - 29
false - 16
false - 17
false - 17
false - 17
false - 18
Another a bit shorter solution:
let sorted = array.sorted { t1, t2 in
if t1.isPriority == t2.isPriority {
return t1.ordering < t2.ordering
}
return t1.isPriority && !t2.isPriority
}
-
This is very good thank you. It can be written more tersely - I will add to your answer.tobygriffin– tobygriffin2015年04月09日 23:42:23 +00:00Commented Apr 9, 2015 at 23:42
-
6My edit to your answer was rejected, so here is the code I used.
let sorted = array.sorted { t1, t2 in
if t1.isPriority == t2.isPriority {
return t1.ordering < t2.ordering
}
return t1.isPriority && !t2.isPriority
}
tobygriffin– tobygriffin2015年04月10日 01:07:00 +00:00Commented Apr 10, 2015 at 1:07 -
Shouldn't
array.sorted
bearray.sort
?Crashalot– Crashalot2016年07月19日 22:31:10 +00:00Commented Jul 19, 2016 at 22:31 -
@Crashalot yeah. But in old swift it was '.sorted'Dejan Skledar– Dejan Skledar2016年07月20日 05:23:06 +00:00Commented Jul 20, 2016 at 5:23
-
@DejanSkledar makes sense, but perhaps an edit is in order for new Swift users?Crashalot– Crashalot2016年07月20日 19:04:15 +00:00Commented Jul 20, 2016 at 19:04
Here is a simple statement to do this sorting:
var sorted = array.sort { 0ドル.isPriority == 1ドル.isPriority ? 0ドル.ordering < 1ドル.ordering : 0ドル.isPriority && !1ドル.isPriority }
-
sort
sorts an array in place; you needsorted
here, as you're creating a new array.adamjansch– adamjansch2025年04月24日 15:01:14 +00:00Commented Apr 24 at 15:01
Conform to Comparable
! 😺
extension Sortable: Comparable {
static func < (sortable0: Sortable, sortable1: Sortable) -> Bool {
sortable0.isPriority == sortable1.isPriority
? sortable0.ordering < sortable1.ordering
: sortable0.isPriority
}
}
Which will allow for:
sortableArray.sorted()
I created a blog post on how to this in Swift 3 and keep the code simple and readable.
You can find it here:
http://master-method.com/index.php/2016/11/23/sort-a-sequence-i-e-arrays-of-objects-by-multiple-properties-in-swift-3/You can also find a GitHub repository with the code here:
https://github.com/jallauca/SortByMultipleFieldsSwift.playground
The gist of it all, say, if you have list of locations, you will be able to do this:
struct Location {
var city: String
var county: String
var state: String
}
var locations: [Location] {
return [
Location(city: "Dania Beach", county: "Broward", state: "Florida"),
Location(city: "Fort Lauderdale", county: "Broward", state: "Florida"),
Location(city: "Hallandale Beach", county: "Broward", state: "Florida"),
Location(city: "Delray Beach", county: "Palm Beach", state: "Florida"),
Location(city: "West Palm Beach", county: "Palm Beach", state: "Florida"),
Location(city: "Savannah", county: "Chatham", state: "Georgia"),
Location(city: "Richmond Hill", county: "Bryan", state: "Georgia"),
Location(city: "St. Marys", county: "Camden", state: "Georgia"),
Location(city: "Kingsland", county: "Camden", state: "Georgia"),
]
}
let sortedLocations =
locations
.sorted(by:
ComparisonResult.flip <<< Location.stateCompare,
Location.countyCompare,
Location.cityCompare
)