I haven't used playgrounds very much with Swift. Mostly I've been using it in projects, so I'm a little lost in dealing with playgrounds.
I've got this test code in a small playground:
let array = [7, 3, 4, 9, 2, 12, 5]
let firstSorted = array.sorted(<)
let secondSorted = sorted(array, <)
let thirdSorted = array.sorted { $0 < $1 }
The output that's shown on the right shows the sorted array output next to firstSorted and secondSorted. The output next to thirdSorted just says (15 times) however.
Why? And how do I see the output, without adding a separate println command to log the output?
The third form has a trailing closure with the parameters specified by their positions.
The other two are a still shorter form that takes just the comparison operator, which happens to match the signature of the closure that's needed.
Another question: (this time about the language, not playgrounds) Why do both the sorted(array, <)
and array.sorted(<)
forms work? The first is a global function that takes 2 parameters, and the second form is a method on the Array class.
It’s because the closure you are passing into sorted
is called by sorted
to do 13 element comparisons as it sorts the array, plus the call to sorted
itself. Whenever a line of code you’ve written is run in the playground it displays either the result of the expression or a count. Because the same line is evaluated multiple times, the IDE can’t show everything so it just shows the count.
If you break it out into multiple lines, you can see the result from sorted
, as well as the results of the 13 evaluations of $0 < $1
:
I guess the IDE could take the approach that the outermost result is the most interesting, and show that, but that might hide the information that your closure is being called multiple times.
As to the second question: the global 2-argument version of sorted
is more general. It sorts any kind of sequence:
// they should probably rename this placeholder to S...
func sorted<C : SequenceType>
(source: C, isOrderedBefore: (C.Generator.Element, C.Generator.Element) -> Bool)
-> [C.Generator.Element]
so you can pass in anything that conforms to SequenceType
:
// results in [4,3,2,1,0]
sorted(0..<5, >)
// results in [(3,"bob"),(2,"fred")] because dictionary’s
// SequenceType representation is unordered pairs
sorted([2:"fred",3:"bob"]) { $0.1 < $1.1 }
Also, since the global function can overload based on constrained inputs, there can be an overloaded version that doesn’t need a comparator at all if the input sequence’s element is Comparable
:
func sorted<C : SequenceType where C.Generator.Element : Comparable>
(source: C) -> [C.Generator.Element]