Range in Swift: The elemental one
Discover the enhanced version of the article, complete with refined syntax highlighting and all the latest updates, now available on my personal blog! Your feedback and engagement are greatly appreciated and help fuel future content:
Well, how many times have you used the code below?
let myArray = [1,2,3,4,5,6,7,8,9,10]
Or , maybe , when someone asked you to fetch first five items from an array
var myModifiedArray = [Int]()for currentNumber in 0..<5 {
myModifiedArray.append(myArray[currentNumber])
}
Well, what if i tell you, you can do it in a better and cleaner way !
// Create an Array of first 10 elements
var myArray = Array(1...10)// Creating a new array with first five elements of previous array
let myModifiedArray = myArray[0…4]
There are 3 main categories for ranges —
- Closed Ranges :
ClosedRange
andCountableClosedRange
- Half-Open Ranges :
Range
andCountableRange
- One-Sided Ranges :
PartialRangeUpTo
,PartialRangeThrough
andPartialRangeFrom
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.
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.
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 boundPartialRangeThrough
: It only has an upper bound and is represented by … (three dots) followed by an upper bound. It includes the upper boundPartialRangeUpTo
: It only has an upper bound and is represented by ..< (two dots followed by less than operator) . It does not include the upper bound.
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.
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.
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 !
Or, Even if we try to directly iterate over our 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.
Well, that’s it from my side !
You can connect with me on LinkedIn 👱🏻 or can get in touch with me via other channels 📬