## SOLVED: Sorting with many, many criteria

 Mar '23 The use case I have is driving me to a sort that depends on over 30 criteria and as they would almost never all be needed I suspect the performance impact is not large (usually the first criterion is all that would be evaluated). My question is whether there is a powerful syntax the lets me avoid this: ``````regattaList.selectedRegatta.skippers.sort { return (\$0.regattaNet, \$0.places[1], \$0.places[2], etc. etc. ) < ( \$1.regattaNet, \$1.places[1], \$1.places[2], etc. etc. ) }`````` 2 Mar '23 Rather than create some massive `sort` closure where you try to account for 30 something properties, step back and take a higher-level look at the problem. What does it mean for two items of whatever type `skippers` is to be sorted? Figure that out and then make your struct conform to `Comparable` by implementing `static func < (lhs:rhs) -> Bool`. Then, instead of a big massive `sort` function like this: ``````regattaList.selectedRegatta.skippers.sort { return (\$0.regattaNet, \$0.places[1], \$0.places[2], etc. etc. ) < ( \$1.regattaNet, \$1.places[1], \$1.places[2], etc. etc. ) }`````` you can simply do this: ``regattaList.selectedRegatta.skippers.sorted()`` because the items in `skippers` already know how to sort themselves. It's kind of hard to say anything more specific without seeing some sample data and examples of how they should sort. 3 Mar '23 Thanks again! I woke up this morning with the idea of needing my own sort method, but was not sure if I could just paste it in the closure... Creating the func < certainly looks like the answer. 2 Mar '23 FYI, when I created my own sort method func <, I learned something interesting about the way the simple sorting closure works with multiple criteria : ``````regattaList.selectedRegatta.skippers.sort { return (\$0.regattaNet, \$0.places[1], ) < ( \$1.regattaNet, \$1.places[1], ) }`````` The syntax above only says what to do when \$0 is < \$1 for example but in fact, when there are multiple criteria it has to deal with <, = and > so when I first implemented my sort method I assumed I could check for < and treat the = and > cases as just not < but it affects the way the secondary sort gets used of course so it has to be more explicit than in the simple closure syntax. I ended up with: ``````static func < (lhs:Skipper, rhs:Skipper) -> Bool { if lhs.regattaNet < rhs.regattaNet { return true } else if lhs.regattaNet > rhs.regattaNet { return false } else if comparePlaces(first: lhs, second: rhs) == 1 { return true } else if comparePlaces(first: lhs, second: rhs) == 2 { return false } else if lhs.lastScore < rhs.lastScore { return true } else if lhs.lastScore > rhs.lastScore { return false } else if lhs.sailNum < rhs.sailNum { return true } else if lhs.sailNum > rhs.sailNum { return false } else if lhs.countryCode < rhs.countryCode { return true } return false }`````` 2

SPONSORED Superwall lets you build & test paywalls without shipping updates. Run experiments, offer sales, segment users, update locked features and more at the click of button. Best part? It's FREE for up to 250 conversions / mo and the Superwall team builds out 100% custom paywalls – free of charge.

Sponsor Hacking with Swift and reach the world's largest Swift community!