Swift includes two range operators, closed
range and half-closed
range, which are shortcuts for expressing a range of values. Range operators are most commonly used with the for loop. In Objective-C, we have 2 different for loops, the traditional loop and iteration-based loop.
Traditional For Loop
The traditional for loop found in C requires 3 parts: the initialisation, the condition, and the loop expression.
for ( initializer; conditional expression; loop expression )
{
// statements to be executed
}
The initialisation declares (and perhaps assigns to) any variables required. The condition checks a condition, and quits the loop if false. The loop expression is performed exactly once every time the loop ends and then repeats, incrementing or decrementing the variable.
Iterator-based For Loop
This type of for loop is a falsification of the numeric range type of for loop; as it allows for the enumeration of sets of items other than number sequences. It is usually characterised by the use of an implicit or explicit iterator, in which the loop variable takes on each of the values in a sequence or other order able data collection. A representative example in Python is:
for (id object in some_iterable_object)
{
// statements to be executed
}
Where some_iterable_object
is either a data collection that supports implicit iteration (NSArray or NSDictionary for Objective-C, for example), or may in fact be an iterator itself. Some languages have this in addition to another for-loop syntax; notably, PHP has this type of loop under the name for each, as well as a three-expression for loop under the name for.
Range Operators
Swift provides two range operators (a..<b
and a...b
) not found in Objective-C, as a shortcut for expressing a range of values. In the new release of Xcode 6 beta 3, Swift’s very first language change that made a very loud noise is the half-closed range operator, it has been changed from ..
to ..<
. The change was decided for the fact that the old half-closed range and closed range operators are visually similar; adding a less-than-sign (<
) distinguish half-closed ranges from closed range ones. The update enhances visual inspection, making a clear differentiation between half-closed (..<
) and closed (...
) ranges.
Closed Range Operator
The closed range operator (a...b
) defines a range that runs from a
to b
, and includes the values a
and b
. The closed range operator is useful when iterating over a range in which you want all of the values to be used, such as with a for-in loop:
for index in 1...5 {
println("\(index) x 2 = \(index * 2)")
}
// 1 x 2 = 2
// 2 x 2 = 4
// 3 x 2 = 6
// 4 x 2 = 8
// 5 x 2 = 10
Half-Closed Range Operator
The half-closed range operator (a..<b
) defines a range that runs from a
to b
, but does not include b
. It is half-closed because it contains its first value, but not its final value. Half-closed range operators are particularly useful when you work with zero-based lists such as arrays, where it is useful to count up to, but not including, the length of the list:
let companions = ["Amy", "Clara", "Donna", "Martha", "Rose"]
let count = companions.count
for i in 0..<count {
println("Person \(i + 1) is called \(companions[i])")
}
// Person 1 is called Amy
// Person 2 is called Clara
// Person 3 is called Donna
// Person 4 is called Martha
// Person 5 is called Rose
As we already know, the array contains 5 items but 0..<count
only counts as far as 4 (the index of the last item in the array), because it is a half-closed range.
Old Half-Closed Range Operator
Missing the old half-closed range operator?
Other developers started learning Swift since day 1. If you are one of the developers who started since the release of Swift then you might want to put back the old half-closed range operator. Thanks to the Operator Declaration, we can do that.
Operator Declaration
An operator declaration introduces a new infix, prefix, or postfix operator into your program and is declared using the contextual keyword operator. We will be using the infix operator to help bring the old half-closed range operator back.
operator infix .. { associativity none precedence 135 }
func .. (lhs: Int, rhs: Int) -> Range {
return lhs..<rhs
}
for i in 0..10 {
println("index \(i)")
}
// index 0
// index 1
// index 2
// index 3
// index 4
// index 5
// index 6
// index 7
// index 8
// index 9
An infix operator is a binary operator that is written between its two operands, such as the addition operator (+) in the expression 1 + 1.
When to use ranged operators?
Range operators have other uses too, not just returning an index for the for loop, it can also return a substring of strings, arrays, and add indexes in a given range.
Leave a Reply