Подтвердить что ты не робот

Сортировка массива объектов по двум свойствам

Об этом попросили и ответили перед тем, как использовать NSSortDescriptor, где это довольно просто. Но есть ли стандартный способ Swift с использованием Array.sort()?

struct Sortable {
    let isPriority: Bool
    let ordering: Int
}

Сортировка массива Sortables по одному свойству проста:

sort { $0.ordering < $1.ordering }

Но я хочу сортировать по isPriority, а затем по ordering - и я не могу разобраться в простой инструкции, чтобы это произошло.

4b9b3361

Ответ 1

Да есть очень простой способ, используя Array.sort()

Код:

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
})

Сортированный массив:

true - 10
true - 10
true - 12
true - 12
true - 19
true - 29
false - 16
false - 17
false - 17
false - 17
false - 18

Еще одно более короткое решение:

let sorted = array.sorted { t1, t2 in 
   if t1.isPriority == t2.isPriority {
      return t1.ordering < t2.ordering 
   }
   return t1.isPriority && !t2.isPriority 
}

Ответ 2

Вот простой оператор для этой сортировки:

var sorted = array.sort { $0.isPriority == $1.isPriority ? $0.ordering < $1.ordering : $0.isPriority && !$1.isPriority }

Ответ 3

Я создал сообщение в блоге о том, как это сделать в Swift 3 и сохранить код простым и читаемым.

Вы можете найти его здесь:

http://master-method.com/index.php/2016/11/23/sort-a-sequence-i-e-arrays-of-objects-by-multiple-properties-in-swift-3/

Вы также можете найти репозиторий GitHub с кодом здесь:

https://github.com/jallauca/SortByMultipleFieldsSwift.playground

Суть всего этого, скажем, если у вас есть список мест, вы сможете это сделать:

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
        )