@thewildjacko The stride(from:through:by:)
function returns a StrideThrough<Int>
sequence which works exactly like a range does with for in
loops but not in switch
statements.
The stride(from:to:by:)
function returns a StrideTo<Int>
sequence which works exactly like a range does with for in
loops but not in switch
statements.
The switch
statement uses the expression pattern under the hood to implement custom pattern matching. You need to overload the pattern matching operator in this case so that it works with both StrideThrough<Int>
and StrideTo<Int>
sequences like this:
func ~=(lhs: StrideThrough<Int>, rhs: Int) -> Bool {
for value in lhs {
if value == rhs {
return true
}
}
return false
}
func ~=(lhs: StrideTo<Int>, rhs: Int) -> Bool {
for value in lhs {
if value == rhs {
return true
}
}
return false
}
The first overloaded version of the ~=
function takes a StrideThrough<Int>
parameter and an Int
one. It returns true
if the lhs
sequece contains the rhs
value and false
otherwise.
The second overloaded version of the ~=
function takes a StrideTo<Int>
parameter and an Int
one. It returns true
if the lhs
sequece contains the rhs
value and false
otherwise.
You can manually use the pattern matching operator’s custom implementation with both StrideThrough<Int>
and StrideTo<Int>
sequences as follows:
stride(from: 0, through: 8, by: 2) ~= 4 // true
stride(from: 1, to: 10, by: 2) ~= 5 // true
Both of the above lines of code return true
because both of the even and odd StrideThrough<Int>
and StrideTo<Int>
sequences contain the corresponding even and odd Int
values in this case.
You can also use the pattern matching operator with ranges by default like this:
0...9 ~= 4 // true
0..<10 ~= 5 // true
0... ~= 4 // true
...0 ~= -4 // true
..<0 ~= -5 // true
All of the above lines of code return true
because all of the closed, half open and one sided ranges contain the corresponding Int
values in this case. This is exactly why you can actually use ranges in switch
statements by default.
You can now work with both StrideThrough<Int>
and StrideTo<Int>
sequences inside switch
statements too as follows:
func getDescription(for number: Int) -> String {
switch number {
case let negative where negative < 0: return "Negative number"
case stride(from: 0, through: 8, by: 2): return "Even digit"
case stride(from: 1, to: 10, by: 2): return "Odd digit"
case let even where even % 2 == 0: return "Even number"
case let odd where odd % 2 == 1: return "Odd number"
default: return "No description"
}
}
getDescription(for: 4) // "Even digit"
getDescription(for: 5) // "Odd digit"
You use the pattern matching operator’s custom implementation to check if a certain digit is either even or odd in this case.
Please let me know if you have any other questions or more issues about the whole thing when you get a chance. Thank you!