mqueue
mqueue

Reputation: 61

xcode 6 beta 6 sort() does not appear to work as Swift docs say

When trying the following in the playground, I get the following error:

Cannot invoke 'sort' with an argument list of type '([Int], (Int, Int) -> Bool)'

let stuff = [1, 2, 3]
var sortedStuff = sort(stuff, { (left: Int, right: Int) -> Bool in left < right })

Am I doing something wrong?

Upvotes: 2

Views: 2875

Answers (1)

Martin R
Martin R

Reputation: 539815

sort() sorts an array in-place:

var stuff = [3, 2, 1]
sort(&stuff, { (left: Int, right: Int) -> Bool in left < right })
println(stuff)   // [1, 2, 3]

The first argument of sort() must be the address of a variable array (and it does not return a value). This causes the (misleading) error message, as you are passing an array as the first argument.

What you probably want to use is sorted(), which does not modify the original array and returns a new sorted array:

let stuff = [3, 2, 1]
var sortedStuff = sorted(stuff, { (left: Int, right: Int) -> Bool in left < right })
println(stuff)          // [3, 2, 1]
println(sortedStuff)    // [1, 2, 3]

The function names have changed in one of the earlier beta releases, as mentioned in release notes

Important Changes, Issues Resolved in Xcode 6 beta 1–3
...
The global sort function now mutates its first argument, and a new sorted function always returns a new collection.

so some tutorials may be out-of-date. The Swift books however are regularly updated, so you might want to download a current version.

As mentioned in the comments, you can shorten the closure notation in various ways:

let sortedStuff = sorted(stuff, { left, right in left < right })  // Inferring type from context
let sortedStuff = sorted(stuff, { $0 < $1 })  // Shorthand argument names
let sortedStuff = sorted(stuff, <)  // Using an operator function

All this is described in detail in the "Closures" chapter of the Swift book.


Update for Swift 2 (Xcode 7): Returning a sorted array is called "sort" again, but it is a (protocol extension) method now instead of a global function:

let stuff = [3, 2, 1]
let sortedStuff = stuff.sort(<)
print(sortedStuff)   // [1, 2, 3]

and sorting an array in place has been renamed to "sortInPlace":

var stuff = [3, 2, 1]
stuff.sortInPlace(<)
print(stuff)   // [1, 2, 3]

Upvotes: 7

Related Questions