Scala大型列表中的模式匹配案例

时间:2015-02-25 07:19:17

标签: scala pattern-matching scala-collections

对于在有限域内返回值的案例的长列表,如何减少案件声明的数量增加?例如,考虑

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

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

3 个答案:

答案 0 :(得分:6)

您可以对案件进行分组:

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

答案 1 :(得分: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"
}

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

答案 2 :(得分:1)

你可以通过这样做来改变复杂性:

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

 m("abc")  // 1
 m("z")    // 0

因此避免了通过getMatch函数调用内容的需要。每次你需要调用getMatch时,你可以提前工作,而不是遍历键。