user3199999 user3199999 - 5 months ago 24
Swift Question

.rangeOfString() with switch in Swift

I want to check if my input has a rangeOfString must with a lot of different strings to check.

basically this if statement but using a switch to check a big list of different strings

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


I've tried doing this but it isn't working.

switch input {
case rangeOfString("lol"):
println("lol")
case rangeOfString("dw"):
println("dw")
default:
println("Default")
}

Answer

While the others answers are probably right about if being a better way to go, you can do something like this via 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 via overloading of 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")
}

is because there is a definition of the ~= operator that matches any kind of Comparable type to an interval:

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

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

In theory you could skip the creation of the 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 would work, but would be a bad idea because now you'll have changed the way switches on strings work universally so that partial matches are always true, which could lead to some unpleasant and unexpected behaviour elsewhere in your code.