In Swift 5.8 we can create a range with special syntax. For example, the numbers 0, 1 and 2 are a range. It is possible to loop over a range.
With startIndex
and endIndex
, we can test the bounds of a range. Count
returns the number of elements. And index()
with offsetBy
changes the start or end.
Here we create a constant range of the values 0, 1 and 2. With this syntax, the 0 and the 2 are both included. We use a for-in
loop over the range.
// Create a range. let range = 0...2 // Use a for-in loop over the range. for value in range { print(value) }0 1 2
StartIndex
, endIndex
This example shows the startIndex
and endIndex
properties. These return the first and last indexes in the range.
EndIndex
here is one greater than the last included value.Int
that is equal to the number of values within the range. Here that is 6.let range = 5...10 // A range has a startIndex and an endIndex. // ... The endIndex is one more than the last included index. print(range.startIndex) print(range.endIndex) // Count returns the number of elements in the range. print(range.count)inRange(5) pastEnd 6
In Swift we can create ranges that do not include the second (end) number. These use a "less than" sign. These are called half-open ranges.
// This range does not include the last number. let values = 0..<5 // Loop over values in the exclusive-end range. for value in values { print(value) }0 1 2 3 4
Usually ranges have positive starts and ends. But we can have negative numbers in our ranges. The start (even if negative) must be less than the end.
for-in
loop. This makes for simpler code.// A range can start at a negative number. for id in -4...2 { print(id) }-4 -3 -2 -1 0 1 2
Index
, offsetBy
Sometimes we want to create a range based on an existing one. We can use index (with offsetBy
) on the startIndex
or endIndex
. Here we increment the range's start by 2.
index()
we can reduce an index by passing a negative Int
as the second argument.var range = 0...3 // Create a new range based on an existing range. // ... Advance the startIndex by 2. var x = range.index(range.startIndex, offsetBy: 2)..<range.endIndex // Display ranges. print(range) print(x)0...3 inRange(2)..<pastEnd
A range's start must be less than or equal to its end. It cannot be larger. Here we encounter the "can't form Range" error in a compiled Swift program.
// This will cause an error. var range = 100...0 // Not reached. print(range)fatal error: Can't form Range with end < start (lldb)
A half-open range can return all valid indexes for an array. The end is one less than the count. Here we use for-in
on all array indexes.
// This string array has three elements. let animals: [String] = ["bird", "cat", "fox"] // Loop through all indexes in the array. for index in 0..<animals.count { print(index) print(animals[index]) }0 bird 1 cat 2 fox
Substring
noteRanges are useful when taking substrings. The index()
offsetBy
method helps us index into a string
. And then we can access the string
by a range.
Range syntax has been changed in Swift 2 and Swift 3. This is confusing. But in many ways the newer syntax forms are clearer and easier to use.
Ranges are used with arrays and strings. They can create a sequence for a for-in
loop. Closed ranges, and half-open ones, are common in Swift programs.