@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!