WWDC22 SALE: Save 50% on all my Swift books and bundles! >>

SOLVED: captainFirstSorted Explained

Forums > 100 Days of SwiftUI

Just finished reviewing Day 9 Closures and was hoping someone could explain how the captainFirstSorted works.

I understand the coding syntax but am not sure how it all works. The array "team" has four strings but the captainFirstSorted function has only two strings as parameters. Does the code somehow iterate through the array? Is that taken care of by the sort() function?

Thanks.


func captainFirstSorted(name1: String, name2: String) -> Bool {
    if name1 == "Suzanne" {
        return true
    } else if name2 == "Suzanne" {
        return false
    }

    return name1 < name2
}

let captainFirstTeam = team.sorted(by: captainFirstSorted)
print(captainFirstTeam)

   

Sometimes you need a different pairs of glasses to see the problem more clearly.

Let's look at a different example. Dump all the forks, spoons, and ONE knife on your kitchen table. How would you sort these? What's a good way to sort knives, forks, and spoons?

There isn't a way, is there? So you have to provide the rules. If you decide to sort them alphabetically, you will be comparing the whole pile, but will do it two pieces at a time.

Is this fork greater than this spoon? Is this knife greater than this fork?

As you look at the pile and sort them you are making this comparison over and over and over and over again. You keep doing this comparison until they are all sorted from forks, the knife, then all the spoons.

Now, add a new rule. The knife should ALWAYS be sorted on the top. So introduce a new comparison in your rule. IF the object on the left is a knife, then it is GREATER than the other object, end of story. If the object on the right is a knife, then it is GREATER than the other object, full stop.

In short, the rules in the sorting algorithm state that if you give me two pieces of cutlery, I should sort them alphabetically. UNLESS one of them is a knife. If either is a knife then it is sorted higher than the other item.

// If you have 50 forks, spoons, and knives on your table, 
// the sorted() function may be called 100s of times!
// Each time the sorted() function is called, it uses these rules.
// The sorted function only compares two items at a time.
func knifeFirstSorted(cutleryOne: String, cutleryTwo: String) -> Bool { 
    if cutleryOne == "knife" { return true } // It's true, the KNIFE is greater than the other object
    else if cutleryTwo == "knife" { return false } // It's false, the other object is NOT greater than the knife.
    return cutleryOne < cutleryTwo  // Otherwise, sort alphabetically
}

// Send in cutlery specific sorting rules
let sortedCutleryDrawer = cutlery.sorted(by: knifeFirstSorted)  
print(sortedCutleryDrawer)

   

If it helps, the function signature for sorted(by:) is this:

func sorted(by areInIncreasingOrder: (Element, Element) throws -> Bool) rethrows -> [Element]

As you can see, the parameter name for the closure you pass to sorted(by:) is areInIncreasingOrder. So the purpose of your closure is to be given two elements from the array being sorted and report back to the system whether or not those two items are already sorted in increasing order, i.e., does the 2nd element come after the 1st element? The system will loop through the array, passing in two elements at a time and reordering them (or not) based on the answer it gets from your closure.

   

Thank you both for your help. Much appreciated. I hope you don't mind but I have a couple of questions for futher clarification.

1) @Obelix , when you say "If the object on the right is a knife, then it is GREATER than the other object, full stop.". What do you mean by "full stop". 2) The function is defined to return a Bool. The If statements obviously return a Bool; however, the final return statement is "return cutleryOne < cutleryTwo //Otherwise, sort alphabetically". I don't recognize that as a Bool. Is it?

   

cutleryOne < cutleryTwo is a statement that is either true or false (i.e., a Bool), yes?

So return cutleryOne < cutleryTwo returns either true or false, depending on the outcome of the comparison. In other words, it returns a Bool.

   

Much appreciated. Thanks!

   

Come for the Swift, get a free English lesson on the side!


Haus asks:

When you say "If the object on the right is a knife, then it is GREATER than the other object, full stop.". What do you mean by "full stop".

Full Stop is a Briticism. Maybe it's said elsewhere in the world, but used quite a bit in Britain.

At the end of sentences you'll see a small dot of punctuation. In US and Canada, it's call a period. Not sure what's used in Australia, New Zealand and other english speaking locales. In Britain, however, it's call a full stop.

When used in the context above, it's usually meant to add emphasis to the statement. Often the implication is there is nothing more to be said.

So when I said

"If the object on the right is a knife, then it is GREATER than the other object, full stop."

I was pointing out that no other evaluation was necessary. The knife object is always greater than anything else it is compared to. Nothing more to say.

   

Save 50% in my Black Friday sale.

SAVE 50% To celebrate WWDC22, all our books and bundles are half price, 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!

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

Reply to this topic…

You need to create an account or log in to reply.

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.