.rangeOfString () with switch in Swift

I want to check if my input has a rangeOfString value with a lot of different lines to check.

basically it is an if statement, but using a switch to check a large list of different lines

if (input.rangeOfString("lol") != nil) { println("yes") } 

I tried to do this, but it does not work.

 switch input { case rangeOfString("lol"): println("lol") case rangeOfString("dw"): println("dw") default: println("Default") } 
+6
source share
3 answers

While the rest of the answers are probably correct so that if best way, you can do something similar using heroic abuse of the ~= operator:

 import Foundation struct Substring { let substr: String init(_ substr: String) { self.substr = substr } } func ~=(substr: Substring, str: String) -> Bool { return str.rangeOfString(substr.substr) != nil } let input = "contains wat" switch input { case Substring("lol"), Substring("wat"): println("huh?") // this one is picked case Substring("dw"): println("dw") // you can also mix and match case "Explicit full string": println("matches whole string") default: println("Default") } 

Switch statements in Swift can be extended by overloading the ~= operator. So, for example, the reason this works:

 switch 2.5 { case 0...5: println("between nought and five") default: println("not in range") } 

lies in the fact that there is a definition of the ~= operator that matches any Comparable type for the interval:

 func ~=<I : IntervalType>(pattern: I, value: I.Bound) -> Bool 

Here, by creating a new type of Substring , I created a way to match strings to substrings.

In theory, you can skip creating a Substring type and do the following:

 func ~=(substr: String, str: String) -> Bool { return str.rangeOfString(str) != nil } let input = "contains lol" switch input { case "lol": println("lol") case "dw": println("dw") default: println("Default") } 

This will work, but it will be a bad idea, because now you change the way you work with strings, universal so that partial matches are always true, which can lead to unpleasant and unexpected behavior elsewhere in your code.

+4
source

You misunderstood the idea of ​​a switch . It checks the value of one expression for several possible values ​​and, if necessary, allows you to access the associated values ​​of the enumeration. It does not allow passing one value to several expressions listed as switching cases * and choosing which one provides the first match.

You need to do an if - else chain to make your code work:

 if (input.rangeOfString("lol") != nil) { println("lol") } else if (input.rangeOfString("dw") != nil) { println("dw") } else { println("Default") } 

I would like to check if a word is used in the input file, and I have 50 words that I would like to check.

Then switch is not a good alternative either. Create a container of words that you want to find, and use filter to find all matches:

 let input = "hahalolblah" let words = ["lol", "blah", "hello"]; let matches = words.filter {input.rangeOfString($0) != nil} println(matches) // Produces [lol, blah] 

* It turns out that switch allows you to pass a single expression to overriding the ~= operator along with the values ​​coming from the case switch . See this answer for more details.

+6
source

You can also do something like:

 switch true { case myString.rangeOfString("lol") != nil: print("lol"); case myString.rangeOfString("dw") != nil: print("dw"); default: print("Default") } 
0
source

Source: https://habr.com/ru/post/985072/


All Articles