Types of ranges

There are multiple types of ranges in Swift you can use. The easiest way of working with them is by making use of the range operator. Let’s go over the different types available in Swift.

Closed range operator going from a…b

let range: ClosedRange = 0...10

print(range.first!) // 0

print(range.last!) // 10

A closed range operator going from a...b defines a range that includes both a and b in which a must not be greater than b .

The closed operator is useful if you’d like to use all the values. For example, if you’d like to iterate over all elements of a collection:

let names = ["Antoine", "Maaike", "Jaap"]

for index in 0...2 {

print("Name \(index) is \(names[index])")

}

// Name 0 is Antoine

// Name 1 is Maaike

// Name 2 is Jaap

The different types of operators can also be used to select elements from a collection. For this, however, we need to make use of the CountableClosedRange type:

let names = ["Antoine", "Maaike", "Jaap"]

let range: CountableClosedRange = 0...2

print(names[range]) // ["Antoine", "Maaike", "Jaap"]

Obviously, Swift is smart enough to detect the countable variant by itself. Therefore, you could write the above code as follows:

let names = ["Antoine", "Maaike", "Jaap"]

print(names[0...2]) // ["Antoine", "Maaike", "Jaap"]

Half-open range operator going from a..<b

let range: Range = 0..<10

print(range.first!) // 0

print(range.last!) // 9

A half-open range defines a range going from a to b but does not include b . It's named half-open as it's containing its first value but not its final value. Just like with the closed range, the value of a must not be greater than b .

The half-open operator can be used to iterate over zero-based lists such as arrays and collections in Swift in which you want to iterate up to but not including the length of the list. It’s basically the same as the earlier code example but now we can make use of the count property:

let names = ["Antoine", "Maaike", "Jaap"]

print(names[0..<names.count]) // ["Antoine", "Maaike", "Jaap"]

If we would’ve done the same with a closed operator we would run into the following error:

Fatal error: Array index is out of range

One-sided operator going from a…

A one-sided range operator only defines one side of the bounds, for example, a... or ...b . A one-sided range goes as far as possible in one direction—for example, taking all the elements of an array from the start of the array to index 2:

let names = ["Antoine", "Maaike", "Jaap"]

print(names[...2]) // ["Antoine", "Maaike", "Jaap"]

Or taking all the elements starting from index 1 till the end of the array:

let names = ["Antoine", "Maaike", "Jaap"]

print(names[1...]) // ["Maaike", "Jaap"]

A one-sided range can be used for iteration but only if used with a starting value a... . Otherwise, it's unclear where the iteration should start. Iterating over a one-sided range requires you to manually check where the loop should end as it would otherwise continue indefinitely.