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)
let names = ["Chris", "Alex", "Ewa", "Barry", "Daniella"] let sortedNames = names.sorted(by: { $0 < $1 } ) print(sortedNames) // Prints "["Alex", "Barry", "Chris", "Daniella", "Ewa"]"
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:
let sortedNames = names.sorted(by: { $0.lowercased() < $1.lowercased() } )
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.
let lowercaseSortedNames = names.sorted(by: { $0.localizedLowercase < $1.localizedLowercase } )
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:
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") ]
Sorting them by last name is easy enough, just be sure to include the lastName property:
let sortedPeople = people.sorted(by: { $0.lastName.localizedLowercase < $1.lastName.localizedLowercase } )
Obviously the first names need to be compared as well. You can achieve this by putting the two comparisons into a tuple:
let sortedPeople = people.sorted(by: { ($0.lastName.localizedLowercase,$0.firstName.localizedLowercase) < ($1.lastName.localizedLowercase,$1.firstName.localizedLowercase) } )
[…] Sorting strings in Swift […]
[…] 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, […]