Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift Sort an array with multiple sort criteria [duplicate]

How is an array sorted by multiple criteria in Swift? For example, an array of dictionaries as shown:

items = [
    [
        "item":"itemA"
        "status":"0"
        "category":"B"
    ],[
        "item":"itemB"
        "status":"1"
        "category":"C"
    ],[
        "item":"itemC"
        "status":"0"
        "category":"A"
    ],[
        "item":"itemD"
        "status":"2"
        "category":"A"
    ]
]

This needs to be sorted as follows:

  1. category ASC
  2. status DESC

I have successfully sorted this array based on either condition 1 OR 2, but not both. Below is the code for that:

itemArray.sort({
        $0["category"] < $1["category"])
    })

How can this be expanded to include multiple sort criteria in a given order?

like image 811
Michael Voccola Avatar asked Dec 15 '22 17:12

Michael Voccola


1 Answers

You want a lexicographic comparison i.e. if the first fields are equal, compare the second fields, otherwise compare the first fields.

The dictionary complicates it a bit since you don’t want to fetch the data out twice and keys may be missing, but that’s actually fine since == and < can handle optional comparisons.

let result = items.sorted {
    switch ($0["category"],$1["category"]) {
    // if neither “category" is nil and contents are equal,
    case let (lhs,rhs) where lhs == rhs:
        // compare “status” (> because DESC order)
        return $0["status"] > $1["status"]
    // else just compare “category” using <
    case let (lhs, rhs):
        return lhs < rhs
    }
}

There’s actually a lexicographicCompare that you could use under some circumstances to do the comparison – but it won’t work in this case because a) optionals, while they can be compared with <, don’t conform to Comparable so you’d have to check for nils manually, and b) you want to sort the second entry in descending order.

like image 124
Airspeed Velocity Avatar answered Mar 07 '23 10:03

Airspeed Velocity