Blast from the Past: Array sorting in Swift 1

This was originally posted in July 2014 on my personal website. It describes the syntax of array sorting as it was in Swift 1.0. I’m sharing it here for posterity, as it’s interesting to reflect on how much the language has evolved (see end for Swift 3 equivalent).

Treating functions as first-class citizens in Swift makes sorting arrays super simple. The global sort and sorted functions each provide sorting behaviour by passing in an array – mutable or immutable, respectively – and a function.

For example, common comparators can be reused by declaring them as functions in the global scope:

var names = [“Bob”, “Larry”, “Samantha”, “Jeffrey”, “Xavier”]
func inOrder(s1: String, s2: String) -> Bool {
    return s1 < s2
sorted(names, inOrder)

This prints the names in alphabetical order by comparing each string in the array to get the result: [“Bob”, “Jeffrey”, “Larry”, “Samantha”, “Xavier”].

Sorting can be tidier and shorter than that, though. Closures can be passed in without defining an explicit global function:

sorted(names) { (s1: String, s2: String) -> Bool in return s1 < s2 }

Argument types can be inferred from context, reducing the length of the closure:

sorted(names) { s1, s2 in return s1 < s2 }

return can be omitted entirely:

sorted(names) { s1, s2 in s1 < s2 }

Argument names $0, $1, etc can be used rather than explicit identification, however some would prefer to put in the extra characters to make the purpose of each variable explicit to help better define the closure.

For simple cases like this, shorthand helps keep things short:

sorted(names) { $0 < $1 }

Even shorter still, in this case, the comparison operator function itself can be passed in:

sorted(names, <)

This works because Swift allows operators to be overridden. The < operator here identifies the overridden operator function.

While sorted returns a copied array created by sorting the elements of the passed-in array, sort is useful to sort a mutable array in-place:

var list = [“Bob”, “Larry”, “Samantha”, “Jeffrey”, “Xavier”]
sort(&list, <)

For further reading, check out the ‘Closures’ chapter in Apple’s excellent ‘The Swift Programming Language’ in the iBooks Store.

The use of a global function here looks alien by Swift 3 standards, but it was necessary because protocol extensions weren’t available until Swift 2.

Nowadays, there’s a strong preference for adding behaviour as a function on the subject itself, which makes a lot more sense: [3, 2, 1].sorted() in contrast to sorted([3, 2, 1]). The function names are the same as in Swift 1, so sort mutates the current array and sorted returns a new immutable one. And it’s still possible to pass in just the operator as the sorting function: [3,2,1].sort(by: >).