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.

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 
}
Sign up to request clarification or add additional context in comments.

7 Comments

This is very good thank you. It can be written more tersely - I will add to your answer.
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 }
Shouldn't array.sorted be array.sort?
@Crashalot yeah. But in old swift it was '.sorted'
@DejanSkledar makes sense, but perhaps an edit is in order for new Swift users?
|
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 }

1 Comment

sort sorts an array in place; you need sorted here, as you're creating a new array.
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()

Comments

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
        )

Comments

Your Answer

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.