【问题标题】:Scala large listing of cases in pattern matchingScala 模式匹配中的大量案例列表
【发布时间】:2015-04-27 02:38:50
【问题描述】:

对于在有限域内返回值的一长串案例,如何减少原本不断增长的案例声明数量?例如考虑

"abc" match {
  case "a"   => 1
  case "ab"  => 1
  case "aw"  => 2
  case "hs"  => 2
  case "abc" => 1
  case _     => 0
}

试过Map[Set[String],Int]哪里

val matches = Map( Set("a","ab","abc") -> 1, Set("aw","hs") -> 2 )

并定义

def getMatch(key: String, m: Map[Set[String],Int]) = {
  val res = m.keys.collectFirst{ case s if s(key) => m(s) }
  res.getOrElse(0)
}

有没有更简单和/或更有效的方法?

【问题讨论】:

  • 嗯...对于与此类似的情况,为什么要通过添加对所有键进行迭代的需要来降低性能?为什么不自己使用Maps 呢?只需拥有Map[ String, Int ] 并将所有“案例”放入其中。
  • 非常感谢您的想法,这也是一个可行的解决方案,尽管减少值的重复性也在查询范围内。

标签: scala pattern-matching scala-collections


【解决方案1】:

您可以对您的案例进行分组:

"abc" match {
  case "a" | "ab" | "abc"   => 1
  case "aw" | "hs"  => 2
  case _     => 0
}

【讨论】:

    【解决方案2】:

    您可以像这样创建自己的匹配器:

    class InSet[T](set: Set[T]) { 
      def unapply(t: T) = set.find(t) 
    }
    val set1 = new InSet(Set("a","ab","abc"))
    val set2 = new InSet(Set("aw","hs"))
    "aw" match { 
      case set1(a) => "1, " + a
      case set2(a) => "2, " + a
      case _ => "3"
    }
    

    这样做的好处是它可以轻松创建和应用非常不同的匹配器。

    【讨论】:

      【解决方案3】:

      您可以通过这样做稍微改变复杂性:

       val m = matches.flatMap { case (xs,i) => xs.map(_ -> i) }.withDefaultValue(0)
      
       m("abc")  // 1
       m("z")    // 0
      

      因此避免了通过 getMatch 函数调用事物的需要。可能也更快,因为您预先完成工作,而不是每次需要调用 getMatch 时都遍历键。

      【讨论】:

        猜你喜欢
        • 2013-09-13
        • 2017-02-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-25
        • 1970-01-01
        • 2016-08-13
        相关资源
        最近更新 更多