top of page

Range in Swift

Updated: May 9, 2024


A collection of mini cars

Well, how many times have you used the code below?

Or , maybe , when someone asked you to fetch first five items from an array

Well, what if i tell you, you can do it in a better and cleaner way !

Not bad, Right ?

There are 3 main categories for ranges —

  1. Closed Ranges : ClosedRange and CountableClosedRange

  2. Half-Open Ranges : Range and CountableRange

  3. One-Sided Ranges : PartialRangeUpTo , PartialRangeThrough and PartialRangeFrom

We can use .contains(anElement) on a range to check if certain element exists inside a range.

You might be wondering:

What’s the difference between a normal range and a countable one? Isn’t a range supposed to be countable?

A short answer would be, No! And there’s a really good and logical explanation to it as well. I’ll explain that later in this article .

Closed Ranges

A Closed Range is a category which is essentially defined using an upper and lower bound and have (three dots) between the bounds . Both upper and lower bounds are included in the range


Example of closed ranges

ClosedRange and CountableClosedRange is essentially the same but in case of CountableClosedRange , the bound that you are specifying should conform to Strideable protocol and bound.stride should conform to SignedInteger which, in short, means we can only create CountableClosedRange with bounds like Int , Int8 , Int16 , Int32 , Int64

And, you must be like:

Wait, not even Double ?

...like I said, I’ll get back to that soon !

Half-Open Ranges

Half-Open range, which is represented by Range , is a category which is pretty much the same as Closed Range but differs in the fact that, first of all, is represented by ..< (two dots followed by less than operator) and it does not include the upper bound in the range.


Example of half-open ranges

CountableRange follows the same rules as explained earlier for CountableClosedRange

One-Sided Ranges

One-Sided ranges only contains one bound and that too on one side of the range only (i.e. they can only contain either a lower or upper bound depending on the type). One-Sided range can be represented by one of the following :

  • PartialRangeFrom : It only has a lower bound and is represented by lowerBound followed by (three dots). It includes the lower bound

  • PartialRangeThrough : It only has an upper bound and is represented by (three dots) followed by an upper bound. It includes the upper bound

  • PartialRangeUpTo : It only has an upper bound and is represented by ..< (two dots followed by less than operator). It does not include the upper bound.


Example of one sided ranges

Now comes the part:

Why we cannot use Double as a bound for CountableRange and CountableClosedRange?

Well, first let me tell me you what I mean when i say the word Countable. For the moment just assume that it means you can iterate over it (using a for-in loop).

Let’s first create a CountableClosedRange with bounds of type Int and iterate over it

Example of Closed countable range

Splendid!

As we can see above, we can easily iterate over the range.

Now let’s change our bounds type to Double instead of an Int and see what happens.


Changing the values to double

Oops?

As soon as we try to change the bounds to a double value, we get an error. Even if we try to explicitly provide a CountableClosedRange<Double> , we still can’t get rid of that error, and this time, we get a new error!


Changing the type of double

Or, even if we try to directly iterate over our Double range,


Iterating over double range

This error is a bit more informative as it clearly states that a bound type to be CountableClosedRange , that bound has to conform to SignedInteger protocol which can be Int , Int8 , Int16 , Int32 or Int64 . That clears out the fact that we can only use Int and not Double

But again, WHY ?

Consider this, if we have Int range and we traverse over it, the least number that we can iterate by is 1. Say, from 1…3 , we were traversing by 1 because that’s the least that we can go in Int . But, in case of 1.0…3.0 , the compiler does not know by what factor should we increment as here we can increment by 1,0.1,0.001,0.00001 and there can be infinite possibilities as all are doubles . And thus we cannot iterate over it . And so we cannot declare CountableClosedRange with bounds Double .

But , if you still want to iterate over a Double range in a for-in loop , you can make use of stride(from:to:by:) or stride(from:through:by:) (this overloaded method includes the upper bound) in which the by: parameter defines by what factor you want to increment in each iteration:


How to correctly iterate over double values

Site's author picture

Shubham Bakshi

Been coding since '13. Rode the Apple bandwagon in '18. Some can say it was love at first byte. I engineer apps with such finesse, they practically dance through your device. And if you're a dev feeling lost in the code jungle, fear not! I'm here to be your coding compass, guiding you through the wilderness of curly braces and semicolons.

Website logo
© Bits & Bytes w/ Bakshi. All rights reserved.
bottom of page