Сортировка массива словаря (или массива объекта пользовательской модели), сохраняющего все дополнительные значения объекта в конце массива - PullRequest
0 голосов
/ 12 ноября 2018

Столкнувшись с проблемой сортировки массива пользовательских объектов, необходимо:

  1. Массив, содержащий объект модели
  2. нужно отсортировать массив, но все объекты (сохраняя объект всех значений optinals в конце массива)
  3. объекты, содержащие информацию, должны стоять на первом месте.

Я пробовал так:

let mSortedFlights = gatesFlightCardArray.sorted(by: { ($0.departureFlight?.flight_number != nil || $0.arrivalFlight?.flight_number != nil) && $0.departureFlight?.time!.localizedStandardCompare(($1.departureFlight?.time!)!) == .orderedAscending  })
                if mSortedFlights.count > 0 {
                    gatesFlightCardArray = mSortedFlights
                }

но это сортировка данных. Укажите ваши данные.

1 Ответ

0 голосов
/ 12 ноября 2018

Метод сортировки не должен сортировать значения nil. Например сортировка этого массива Int? сохраняет нулевые значения и сортирует их до конца:

var a = [0, 10, 3, nil, 5, 7, 2, nil, 4]
a.sort { v0, v1 -> Bool in
    guard let v0 = v0 else {
        return false
    }
    guard let v1 = v1 else {
        return true
    }
    return v0 < v1
}
print(a)

Результат выглядит следующим образом:

[0, 2, 3, 4, 5, 7, 10, nil, nil]

Для вашего примера я не был уверен, по каким критериям вы хотите отсортировать. Итак, я создал пример, с которым вы можете работать. Я сортирую массив сначала по номеру рейса вылета, а затем по номеру рейса прибытия.

let sortedTrips = trips.sorted { trip0, trip1 -> Bool in
    // Sort all trips where either arrival or departure flight are nil to the end
    guard let departureFlight0 = trip0.departureFlight, let arrivalFlight0 = trip0.arrivalFlight else {
        return false
    }
    guard let departureFlight1 = trip1.departureFlight, let arrivalFlight1 = trip1.arrivalFlight else {
        return true
    }
    // Sort by primary criterion of departure flight number
    if departureFlight0.flightNumber < departureFlight1.flightNumber {
        return true
    } else if departureFlight0.flightNumber == departureFlight1.flightNumber {
        // If the departureFlightNumbers of both trips are equal, sort by arrival flight number
        return arrivalFlight0.flightNumber < arrivalFlight1.flightNumber
    } else {
        return false
    }
}
print(sortedTrips, separator: "\n")

Чтобы попробовать это сами, помимо кода сортировки скопируйте мои классы и данные примеров на игровую площадку:

class Flight: CustomStringConvertible {
    private(set) var flightNumber: Int
    private(set) var time: String

    init(flightNumber: Int, time: String) {
        self.flightNumber = flightNumber
        self.time = time
    }

    var description: String {
        return "\(flightNumber) at \(time)"
    }
}

class Trip: CustomStringConvertible {
    private(set) var departureFlight: Flight?
    private(set) var arrivalFlight: Flight?

    init(departureFlight: Flight?, arrivalFlight: Flight?) {
        self.departureFlight = departureFlight
        self.arrivalFlight = arrivalFlight
    }

    var description: String {
        return "\(departureFlight?.description ?? "na") - \(arrivalFlight?.description ?? "na")"
    }
}

var trips = [Trip(departureFlight: Flight(flightNumber: 3, time: "10:45"), arrivalFlight: Flight(flightNumber: 9, time: "12:45")),
            Trip(departureFlight: nil, arrivalFlight: Flight(flightNumber: 9, time: "12:45")),
            Trip(departureFlight: Flight(flightNumber: 3, time: "12:45"), arrivalFlight: Flight(flightNumber: 5, time: "12:45")),
            Trip(departureFlight: Flight(flightNumber: 8, time: "13:48"), arrivalFlight: nil),
            Trip(departureFlight: nil, arrivalFlight: nil),
            Trip(departureFlight: Flight(flightNumber: 4, time: "11:31"), arrivalFlight: Flight(flightNumber: 9, time: "12:45")),
            Trip(departureFlight: nil, arrivalFlight: nil)]
...