33

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.

asked Apr 9, 2015 at 5:41
1

4 Answers 4

64

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 
}
answered Apr 9, 2015 at 6:31
7
  • This is very good thank you. It can be written more tersely - I will add to your answer. Commented Apr 9, 2015 at 23:42
  • 6
    My 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 } Commented Apr 10, 2015 at 1:07
  • Shouldn't array.sorted be array.sort? Commented Jul 19, 2016 at 22:31
  • @Crashalot yeah. But in old swift it was '.sorted' Commented Jul 20, 2016 at 5:23
  • @DejanSkledar makes sense, but perhaps an edit is in order for new Swift users? Commented Jul 20, 2016 at 19:04
17

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 }
answered May 14, 2016 at 6:18
1
  • sort sorts an array in place; you need sorted here, as you're creating a new array. Commented Apr 24 at 15:01
2

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()
answered Mar 13, 2020 at 5:32
1

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
 )
answered Nov 23, 2016 at 21:16

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.