Swift 2 - Pattern matching in if
All it really means is that if statements now support pattern matching like switch statements already have. For example, the following is now a valid way of using if/else if/else statements to "switch" over the cases of an enum.
enum TestEnum {
case One
case Two
case Three
}
let state = TestEnum.Three
if case .One = state {
print("1")
} else if case .Two = state {
print("2")
} else {
print("3")
}
And the following is now an acceptable way of checking if someInteger
is within a given range.
let someInteger = 42
if case 0...100 = someInteger {
// ...
}
Here are a couple more examples using the optional pattern from The Swift Programming Language
let someOptional: Int? = 42
// Match using an enumeration case pattern
if case .Some(let x) = someOptional {
print(x)
}
// Match using an optional pattern
if case let x? = someOptional {
print(x)
}
Pattern matching in a Swift for loop
You can combine a pattern matching conditional cast with a where
clause like so:
let myStuff: [AnyObject] = [5, "dog", 11, 15, "cat"]
// item will be an Int, and divisible by 5
for case let item as Int in myStuff where item % 5 == 0 {
print(item)
}
// Prints:
// 5
// 15
Custom pattern matching in Swift 2.2 not working as expected
switch testLine {
case _ where testLine.characters.count == 0:
print("Empty")
case _ where testLine.isOfType(.Event): print("Event")
case _ where testLine.isOfType(.Data): print("Data")
default: print("Unknown Type")
}
/* prints
Event
*/
still, try to rearrange it ...
it looks terrible, but this works, as expected
enum LineType : String {
case Event = "event:"
case Data = "data:"
}
func ~= (pattern: LineType, value: String) -> Bool {
return value.hasPrefix(pattern.rawValue)
}
let testLine = "event:yada-yada-yada"
let e = LineType.Event
let d = LineType.Data
switch testLine {
case let s where s.characters.count == 0: print("Empty")
case e: print("Event")
case d: print("Data")
default: print("Unknown Type")
}
/* prints
Event
*/
this should also work
...
case { return LineType.Event }(): print("Event")
...
or
...
case { LineType.Event }(): print("Event")
...
Use or logic with multiple if case statements
I would resort to some sort of isBar
property on the enum itself, so that the "a or b" test remains readable:
enum MyEnum {
case foo, bar(_ prop: Int)
var isBar: Bool {
switch self {
case .bar: return true
default: return false
}
}
}
let var1 = MyEnum.foo
let var2 = MyEnum.bar(1)
let eitherIsBar = var1.isBar || var2.isBar
Swift switch matching multiple conditionals
A switch statement compares a value against patterns and executes
the code based on the first successful match.
If your intention is to match against multiple patterns and execute
code for all matches then use multiple if statements.
The same case patterns can be used:
if case (0, 0) = somePoint {
print("\(somePoint) is at the origin")
}
if case (_, 0) = somePoint {
print("\(somePoint) is on the x-axis")
}
// ...
if case (-2...2, -2...2) = somePoint {
print("\(somePoint) is inside the box")
}
// ...
Can I use the range operator with if statement in Swift?
You can use the "pattern-match" operator ~=
:
if 200 ... 299 ~= statusCode {
print("success")
}
Or a switch-statement with an expression pattern (which uses the pattern-match
operator internally):
switch statusCode {
case 200 ... 299:
print("success")
default:
print("failure")
}
Note that ..<
denotes a range that omits the upper value, so you probably want200 ... 299
or 200 ..< 300
.
Additional information: When the above code is compiled in Xcode 6.3 with
optimizations switch on, then for the test
if 200 ... 299 ~= statusCode
actually no function call is generated at all, only three assembly instruction:
addq $-200, %rdi
cmpq $99, %rdi
ja LBB0_1
this is exactly the same assembly code that is generated for
if statusCode >= 200 && statusCode <= 299
You can verify that with
xcrun -sdk macosx swiftc -O -emit-assembly main.swift
As of Swift 2, this can be written as
if case 200 ... 299 = statusCode {
print("success")
}
using the newly introduced pattern-matching for if-statements.
See also Swift 2 - Pattern matching in "if".
String pattern matching in Swift switch statements
I found the issue. I did not isolate the problem correctly.
The issue was that my source data had a slightly different "-" character which Swift (rightly so) did not consider equal to the condition in the switch cases. I sanitized the inputs and now it works correctly. In the playground I did manually write the input so the issue did not arise.
Thank you so much anyway!
Related Topics
Xcode 8 Beta 3: Expected ',' Joining Parts of a Multi-Clause Condition
Storing Values in Completionhandlers - Swift
Fatal Error: Swapping a Location With Itself Is Not Supported With Swift 2.0
Inout Parameter in Async Callback Does Not Work as Expected
Swift: Converting a String into a Variable Name
How to Return Coordinates After Forward Geocoding
Why Do I Need Underscores in Swift
How to Set Uicollectionviewcell Width and Height Programmatically
How to Make a Custom Initializer For a Uiviewcontroller Subclass in Swift
Is There a Swift Alternative For Nslog(@"%S", _Pretty_Function_)
Computed Read-Only Property VS Function in Swift
Load Local Web Files & Resources in Wkwebview
How to Get Mathemical Pi Constant in Swift
Deleting All Documents in Firestore Collection
Iterate Over Object Class Attributes in Swift
How Add Tabs Programmatically in Uitabbarcontroller With Swift