You are probably familiar with Swift's range operator. You can create a range in Swift by using the closed range operator or the half-open range operator. Take a look at these example to freshen up your memory.

let closedRange = 0...10
closedRange.count   // 11

let halfOpenRange = 0..<10
halfOpenRange.count // 10

We can use the closed range operator to create a range that runs from 0 to 10. As the name suggests, the closed range operator includes the last value 10. That is why the count property of closedRange returns 11, not 10.

The half-open range operator also creates a range. The difference is that it runs from 0 to 10, excluding the last value, 10. The count property of halfOpenRange returns 10, not 11.

What Is a One-Sided Range?

In some cases, the closed range operator and the half-open range operator can be used to define a range that continues in one direction as far as possible. Take a look at this example.

let fruits = [
    "apple",
    "orange",
    "apricot",
    "pineapple",
    "lime"
]

fruits[...2]    // ["apple", "orange", "apricot"]

We define an array of strings and use the closed range operator to create an array that contains the first three elements, the elements at index 0, 1, and 2. Notice that the closed range operator doesn't specify a first value. The closed range operator creates a one-sided range, a range that continues in one direction as far as possible.

We can also use the closed range operator and omit the last value of the range. Take a look at this example. We create an array that contains the elements of fruits starting at index 2.

let fruits = [
    "apple",
    "orange",
    "apricot",
    "pineapple",
    "lime"
]

fruits[2...]    // ["apricot", "pineapple", "line"]

The half-open range operator can also be used to create one-sided ranges. Take a look at this example. Note that you can only omit the first value if you create a one-side range with the half-open range operator. You always need to specify the last value.

let fruits = [
    "apple",
    "orange",
    "apricot",
    "pineapple",
    "lime"
]

fruits[..<2]    // ["apple", "orange"]

When Can You Use One-Sided Ranges?

The above examples illustrate that one-sided ranges are useful to create a subarray or an array slice. That is only one application, though. Take a look at this example.

let minimumAge = 28
let maximumAge = 40
let myAge = 42

(minimumAge...maximumAge).contains(myAge)   // false

The constants minimumAge and maximumAge define the age requirements of a service we are developing. We use the values, which can be set dynamically, and the closed range operator to create a range. The contains(_:) method tells us if the range contains the value of myAge.

We can change the example by using a one-sided range. We use the closed range operator to create a one-side range without specifying the first value or the last value.

let minimumAge = 28
let maximumAge = 40
let myAge = 42

(...maximumAge).contains(myAge) // false
(minimumAge...).contains(myAge) // true

You probably won't use one-sided ranges on a daily basis, but they come in useful from time to time. Creating a subarray or array slice using a one-sided range is convenient and it is easy to understand.