4

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?

1
  • 2
    I disagree this is an exact duplicate, since this is about a dictionary input rather than a struct (though it is very similar) Commented Dec 22, 2014 at 4:44

1 Answer 1

12

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Where is .Some(lhs) and .Some(RHS) generated / what do they represent? I would like to better understand this so I can add additional sort order criteria beyond the two in the example.
They were to check if the keys were missing - but then I realized it’s unnecessary since == can handle optionals of comparables. I’ve edited it to remove them.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.