BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

SOLVED: Sorting with many, many criteria

Forums > Swift

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      

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      

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      

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      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.