Sorting strings in Swift

Sorting an array of strings in Swift is a bit of an iceberg topic – it seems fairly manageable, you just call the sort function right? Then you dig a little deeper and find a whole lot more lurking under the surface!

Let’s start with the example in Apple’s Swift Programming Language guide:

(Apple sorts the data in reverse order, for simplicity I’ve swapped it)

[sourcecode language=”javascript”]
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"]
let sortedNames = names.sorted(by: { $0 < $1 } )
print(sortedNames)
// Prints "["Alex", "Barry", "Chris", "Daniella", "Ewa"]"
[/sourcecode]

Great, but what happens if “Alex” starts with a lower case letter? Alex gets shunted to the end of the list – probably not what you’re after!
“Barry”, “Chris”, “Daniella”, “Ewa”, “alex”

To ignore case, compare the lower case versions of the names:

[sourcecode language=”javascript”]
let sortedNames = names.sorted(by: {
$0.lowercased() < $1.lowercased() } )
[/sourcecode]

The rules for ordering strings can vary for different languages and locales. From Apple’s iOS String Programming Guide:

Important: For user-visible sorted lists, you should always use localized comparisons.

Fortunately, strings have another property called localizedLowercase.

[sourcecode language=”javascript”]
let lowercaseSortedNames = names.sorted(by: {
$0.localizedLowercase &lt; $1.localizedLowercase } )
[/sourcecode]

Now let’s add some complexity to this problem. Let’s say we have a Person class, that contains a first name and a last name, and an array of people:

[sourcecode language=”javascript”]
struct Person {
var firstName: String
var lastName: String
}
let people = [
Person(firstName: "Kylie", lastName: "Minogue"),
Person(firstName: "Dannie", lastName: "Minogue"),
Person(firstName: "Paul", lastName: "Kelly"),
Person(firstName: "Ned", lastName: "Kelly")
]
[/sourcecode]

Sorting them by last name is easy enough, just be sure to include the lastName property:

[sourcecode language=”javascript”]
let sortedPeople = people.sorted(by: {
$0.lastName.localizedLowercase < $1.lastName.localizedLowercase } )
[/sourcecode]

Screenshot 2016-08-05 12.57.30

Obviously the first names need to be compared as well. You can achieve this by putting the two comparisons into a tuple:

[sourcecode language=”javascript”]
let sortedPeople = people.sorted(by: {
($0.lastName.localizedLowercase,$0.firstName.localizedLowercase) <
($1.lastName.localizedLowercase,$1.firstName.localizedLowercase)
} )
[/sourcecode]
Screenshot 2016-08-05 13.02.11

Unknown's avatar

iOS development with Swift - book: https://manning.com/books/ios-development-with-swift video course: https://www.manning.com/livevideo/ios-development-with-swift-lv

Tagged with:
Posted in Swift
2 comments on “Sorting strings in Swift
  1. […] go into sorting arrays of strings in more detail here. Of course if you want to sort the array itself rather than return a sorted version of the array, […]

Leave a Reply

Discover more from Before I forget...

Subscribe now to keep reading and get access to the full archive.

Continue reading