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

SOLVED: Can someone explain .sorted(by: ) ?

Forums > 100 Days of SwiftUI

I don't really understand how .sorted(by: ) works. I followed Paul's example from Day 9 but I still don't get it. I see what he did and I can manipulate it to do similar things and with .map and .filter, i can use closures and make them do what I want and it seems to all make sense but .sorted(by: ) isn't clicking with me. Here's his example:

let team = ["Gloria", "Suzanne", "Piper", "Tiffany", "Tasha"]
let sortedTeam = team.sorted()
print(sortedTeam)
// Prints - ["Gloria", "Piper", "Suzanne", "Tasha", "Tiffany"]

let captainFirstTeam = team.sorted { name1, name2 in
    if name1 == "Suzanne" {
        return true
    } else if name2 == "Suzanne" {
        return false
    }
    return name1 < name2
}
print(captainFirstTeam)
// Prints - ["Suzanne", "Gloria", "Piper", "Tasha", "Tiffany"]

I was able to use his code and do similar sorts with .hasPrefix() and .hasSuffix() and that all worked, but I don't understand why. I also tried just messing around with .sorted(by: ) and I'm not really understanding the output I'm getting or how it's all working. I tried this:

let sort1 = team.sorted { name1, name2 in
    return true
}
print(sort1)
// Prints - ["Tasha", "Tiffany", "Piper", "Suzanne", "Gloria"]

let sort2 = team.sorted { name1, name2 in
    return false
}
print(sort2)
// Prints - ["Gloria", "Suzanne", "Piper", "Tiffany", "Tasha"]

4      

Here's an example. Say you gather your family around the dining room table. You dump a box of fruit on the table, and you ask each person to "sort" the fruit. This may not make sense to everyone, as there is no prescribed way to "sort" fruit.

Instead, you give each person a sorting rule.

  • You ask Agnetha to sort the fruit alphabetically, by color.
  • Bjorn sorts the fruit by size: longest to shortest.
  • Anni-Frid sorts the fruit by taste: bland, sweet, then sour.
  • Benny sorts the fruit by weight: lightest to heaviest.

Each is performing a sort function, but you had to specify the sort rules. When comparing two different fruits, what is the rule to determine weight? What is the rule for sorting color?

This is the function of the closure you supply to the sorted(by:) method.

Swift will give the closure two of your fruits (say the banana and the peach. Or the pomegranite and the plum.) It doesn't matter which two fruits it receives, you need to provide the rules to determine if fruit #1 is ordered before fruit #2.

The beautiful thing about closures is you can easily change the sorting rules based on your needs!

In this example below. Think through what you are asking Bjorn to do? You give him two names ("Piper and Gloria", or "Tiffany and Suzanne"). But no matter what the names are, you're just saying returning true. This essentially tells the sort routine that name1 will always be sorted before name2. You're not comparing anything.

To make this more clear, you might want to add a print statement inside and watch the console.

let sort1 = team.sorted { name1, name2 in
    print("\(name1) is before \(name2)")  //  watch the console as Swift sends values to be compared.
    return true  // not really a useful sorting rule, is it?
}
print(sort1)
// Prints - ["Tasha", "Tiffany", "Piper", "Suzanne", "Gloria"]
  • Suzanne is before Gloria
  • Piper is before Gloria
  • Piper is before Suzanne
  • Tiffany is before Gloria
  • Tiffany is before Suzanne
  • Tiffany is before Piper
  • Tasha is before Gloria
  • Tasha is before Suzanne
  • Tasha is before Piper
  • Tasha is before Tiffany

Here's a second example with some better sorting logic. Sort the list of names by how many letters are in each name. Run this in Playgrounds. Do you see how the sortby rule is applied?

let team = ["Gloria", "Ed", "Paul", "Piper", "Tiffany", "Tasha"]
let sortByLength = team.sorted { name1, name2 in
    if name1.count >= name2.count {  // this rule makes a bit more sense.
        print ("\(name1) has more letters than \(name2)")
        return true
    } else {
        print ("\(name1) has fewer letters than \(name2)")
        return false
    }
}
print(sortByLength)

5      

Ok, thanks. By putting the print statements in there I was able to see exactly what it was doing and now it makes sense. I'll probably forget it five minutes from now but at least I can go back and understand it. Thanks, again.

4      

My suggestion about forgetting.....

Create a new playground for Swift concepts.

You can create many pages in a single Playground.

Create a new page to cover specific concepts. Put sample code in each and add a lot of documentation to your future self.

For example one page might simply be titled: Array_SortBy

Then, in future, you can see working code, your notes, and have a quick way to reinforce concepts.

6      

Save 50% in my WWDC sale.

SAVE 50% To celebrate WWDC24, 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!

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.