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
How to use Pattern matching in a Swift for loop for nested array
Not really pattern matching but without a loop
arr2.compactMap{$0.first{$0 is String}}.forEach{print($0)}
compactMap
is necessary because first
returns an optional. The position of the String
in the array is irrelevant.
How to get index in for case pattern matching loop
You can use enumerated()
in conjunction with for case let
, you just need to move the conditional typecasting pattern into the binding of the second element in the tuple.
// note that variable names should be lowerCamelCase – I renamed 'JSON' to 'json'.
for case let (index, playlistData as JSONDictionary) in json.enumerated() {
// ...
}
enumerated()
returns a sequence of pairs of consecutive Int
s starting from 0 (available inside the loop as index
) along with the elements of the sequence you call it on.
how to make sense of pattern matching of optionals in for loop in swift
You want to know why this code:
let names = ["b", nil, "x"]
for case let name? in names {
print(name)
}
Produces this output:
b
x
You are wondering what happens to the nil
.
The answer is the "Optional Pattern" found in the Language Reference:
The optional pattern provides a convenient way to iterate over an
array of optional values in a for-in statement, executing the body of
the loop only for non-nil elements.
The case
keyword is vital. It changes the nature of the for
loop significantly. As you can see from this complier error, name?
inside the loop is not an optional at all.
Think of the ?
as an operator that removes the optionality of name
. If the assignment would result in nil
, that iteration of the loop does not happen, and the next iteration starts.
Notice that without the case
you do not get the same behavior at all.
This:
for name in names {
print(name)
}
Will get this output:
Optional("b")
nil
Optional("x")
And that neither of these work at all.
Swift: Regex search in for loop not progressing
The ([a-zA-Z0-9\-\_]*)*[sS]uper([a-zA-Z0-9\-\_]*)*
pattern you are using is very inefficient and is fraught with catastrophic backtracking. When you place a pattern of unlimited legth (as a+
or a*
) inside a group and set an unlimited quantifier to it (e.g. (a+)+
) and the pattern is not at the end of the regex, catastrophic backtracking is imminent with strings that match the pattern partially, but not fully.
See a demo of your pattern run against a short string like Super
. Look, how hard it is for a regex engine to actually make sure that Super
is the right match for the pattern, with red arrows showing backtracking:
Now, check how fast the pattern becomes if you unwrap the nested quantified patterns and use [a-zA-Z0-9_-]*[sS]uper[a-zA-Z0-9_-]*
, see this demo, with the number of steps reduced from 167 to 13. Note you don't need to escape a _
char (it is a word char), and you do not have to escape -
inside a character class if it is at the start/end of the class.
If you use .caseInsensitive
option (e.g. options: [ .caseInsensitive ]
), you may even shorten the pattern to [a-z0-9_-]*super[a-z0-9_-]*
.
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!
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)
}
Index of enum element in for-case pattern matching
I found solution:
for case let (index, EnumType.A(associatedValue)) in arrayOfEnums.enumerated() {
// operations here
}
Related Topics
Swift Package Manager Unable to Compile Ncurses Installed Through Homebrew
JSONencoder Won't Allow Type Encoded to Primitive Value
Why I Can Not Use Equatable Function in My View When the View Can Use It in Swiftui
Arkit - Collision with Real World Objects
Swift: Generic Overloads, Definition of "More Specialized"
Way to Purge All But One Object Types (Models) in a Realm
How to Specify the Type Information of an Array That Would Hold Swiftui Custom Views
Swiftui [Bug] Navigationview and List Not Showing on iPad Simulator Only
Swiftui Nested Foreach Causes Unexpected Ordering
Swift 3: Int Is Not Convertible to Bool in Bitwise Operation
Name Convention for Unwrapped Value in Swift
Saving Swifty JSON Array to User Defaults
Cannot Invoke Initializer for Type 'Sqlite3_Destructor_Type'
Calculate the Number of Dimensions of a Multi-Dimensional Array in Swift
Swift Firebase Check If User Exists
Swift Delegate Beetween Two Vc Without Segue
Response Struct Does Not Like Codingkeys
Self' Is Only Available in a Protocol or as the Result of a Class Method