【问题标题】:.rangeOfString() with switch in Swift.rangeOfString() 与 Swift 中的开关
【发布时间】:2015-04-13 15:27:16
【问题描述】:

我想检查我的输入是否有 rangeOfString 必须检查很多不同的字符串。

基本上是这个 if 语句,但使用 switch 来检查不同字符串的大列表

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

我试过这样做,但它不起作用。

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

【问题讨论】:

    标签: ios swift switch-statement


    【解决方案1】:

    您误解了 switch 声明的概念。它根据多个可能的值检查一个表达式的值,并可选择让您访问枚举的关联值。它不允许您将单个值传递给列为 switch case* 的多个表达式,并选择提供第一个匹配项的那个。

    您需要创建一个if-elses 链才能使您的代码正常工作:

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

    我想检查输入中是否使用了一个词,并且我想检查 50 个词。

    那么switch 也不是一个好的选择。为您要搜索的单词创建一个容器,然后使用filter 查找所有匹配项:

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

    * 事实证明,switch 允许您将一个表达式传递给 ~= 运算符的覆盖,以及来自 switchcases 的值。详情请见this answer

    【讨论】:

    • 我也认为是这种情况,但不确定。
    • 哇,这似乎是一种非常复杂的方法。
    • 如果我想检查输入中是否使用了一个词,并且我想检查 50 个词。 if-else 语句会很疯狂
    • "它不允许您将单个值传递给多个表达式,并选择提供第一个匹配项的那个。"公平地说,在 Swift 中确实如此,只要你以某种值的形式表达这些表达式...... Swift 开关非常灵活。
    【解决方案2】:

    虽然其他人的答案可能是关于 if 是一种更好的方法,但您可以通过英勇滥用 ~= 运算符来做这样的事情:

    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")
    }
    

    Swift 中的 Switch 语句可以通过 ~= 运算符的重载来扩展。因此,例如,它起作用的原因:

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

    是因为~= 运算符的定义可以将任何类型的Comparable 类型匹配到一个区间:

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

    在这里,通过创建Substring 的新类型,我创建了一种将字符串与子字符串匹配的方法。

    理论上您可以跳过Substring 类型的创建并执行以下操作:

    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")
    }
    

    这可行,但会是一个坏主意,因为现在您将更改字符串开关的通用工作方式,以便部分匹配始终为真,这可能会导致一些不愉快和意外代码中其他地方的行为。

    【讨论】:

    • 喜欢这个。仍然会非常冗长,在 switch 中有 50 种不同的情况。我更喜欢循环遍历数组:D
    • 同意了,但我觉得有点糟糕,这个问题被这么狠狠地打了一顿,因为它可以做到……
    • @Airspeed Velocity 这看起来很有希望!你能多解释一下结构、子集和~=,因为它们对我来说是全新的。在我们发言时,我还在阅读 iOS 开发者库中的相关页面
    • 据我了解,这也让我可以选择在每种情况下做不同的事情,而不是在每个“单词”上做同样的事情。这是一个加号!
    • 是的,没错,你可以匹配多个字符串。已编辑演示。
    【解决方案3】:

    你也可以这样做:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-17
      • 2016-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多