【问题标题】:Refactoring scala match case for list of strings重构字符串列表的scala匹配案例
【发布时间】:2018-10-16 05:32:40
【问题描述】:

我有以下几点:

def myFunc(str: String): Something => {

    str match {
        case "a" | "a1" | "abc" | "qwe" | "23rs" => Something
        case _ => None
    }    
}

字符串列表可能很长,我想将其提取到一个函数中。我真的不知道要搜索什么,因为这样做了

def isSomething(str: String): Boolean => {
  List("a","a1","abc","qwe","23rs").contains(str)
}

但是case isSomething => Something 不起作用

【问题讨论】:

  • 使用 Option monad 会有帮助

标签: scala pattern-matching match


【解决方案1】:

首先您在定义函数时使用了错误的=> 运算符。

scala> def isSomething(str: String): Boolean = {
     |   List("a","a1","abc","qwe","23rs").contains(str)
     | }
isSomething: (str: String)Boolean

scala> def myFunc(str: String): String = {
     | 
     | str match {
     | case str if(isSomething(str)) => "Something"
     | case _ => "None"
     | }
     | }
myFunc: (str: String)String

scala> myFunc("a")
res9: String = Something

我不知道什么是东西所以我把它当作一个字符串。您可以根据您的用例对其进行修改。 希望对您有所帮助。

【讨论】:

    【解决方案2】:

    您的str 是一个字符串,因此与布尔类型的isSomething 不匹配。您的示例代码的另一个问题是 None 是 Option 类型,因此让您的匹配案例返回相同的类型会更有意义。这是使用guard 来处理contains 条件的一种方法:

    val list = List("a", "a1", "abc", "qwe", "23rs")
    
    val s = "abc"
    
    s match {
      case s if list contains s => Some(s)
      case _ => None
    }
    // res1: Option[String] = Some(abc)
    

    【讨论】:

    • 模式匹配是一种相当复杂的表达方式if (list contains s) Some(s) else None
    • 同意if/else更简单直接。我在答案中保留了模式匹配,主要是为了遵循 OP 使用它的明显意图(同时随着列表的增长,不再需要在匹配案例中表达列表内容)。
    【解决方案3】:

    您可以执行以下操作

    val list = List("a", "a1", "abc", "qwe", "23rs")
    
    def myFunc(str: String): Option[String] = {
      list.contains(str) match {
        case true => ??? //calling something function should return Some
        case false => None
      }
    }
    

    Option[String] 可以根据你的返回类型来改变,但是None 建议真正的情况应该返回Option 类型。所以String可以改成你想要的数据类型

    【讨论】:

      【解决方案4】:

      大多数其他答案似乎都涉及修复选项的使用,或远离模式匹配(简单地使用守卫并不是真正的模式匹配,IMO)

      我想您可能会问关于提取器的问题。如果是这样,这可能更接近您想要的:

        case class Something(str: String)
      
        // define an extractor to match our list of Strings
      
        object MatchList {
          def unapply(str: String) = {
            str match {
              case "a" | "a1" | "abc" | "qwe" | "23rs" => Some(str)
              case _                                   => None
            }
          }
          }
      
          def myFunc(str: String): Option[Something] = {
      
            // use our new extractor (and fix up the use of Option while we're at it)    
            str match {
              case MatchList(str) => Some(Something(str))
              case _              => None
            }
          }
      
      // Couple of test cases...
          myFunc("a")    // Some(Something(a))
          myFunc("b")    // None
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-02-13
        • 2015-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 2013-08-30
        • 1970-01-01
        相关资源
        最近更新 更多