Pattern Matching in a Swift for Loop

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 Ints 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.

compiler error using guard on non-optional

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.

Sample Image

Sample Image

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:

Sample Image

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



Leave a reply



Submit