假设我在Scala中有一个Map[String, String]
。
我希望与Map中的全套键-值对进行匹配。
像这样的事情应该是可能的
val record = Map("amenity" -> "restaurant", "cuisine" -> "chinese", "name" -> "Golden Palace")
record match {
case Map("amenity" -> "restaurant", "cuisine" -> "chinese") => "a Chinese restaurant"
case Map("amenity" -> "restaurant", "cuisine" -> "italian") => "an Italian restaurant"
case Map("amenity" -> "restaurant") => "some other restaurant"
case _ => "something else entirely"
}
编译器抱怨道:error: value Map is not a case class constructor, nor does it have an unapply/unapplySeq method
目前,对Map
中的键-值组合进行模式匹配的最佳方式是什么?
6条答案
按热度按时间dnph8jn41#
您可以使用
flatMap
提取您感兴趣的值,然后与它们进行匹配:请参阅this snippets page上的#1。
您可以检查任意键列表是否具有特定的值,如下所示:
请注意,即使Map中没有键,上述方法也有效,但如果键共享某些值,您可能希望使用
map
而不是flatMap
,并在值列表中显式使用Some
/None
。例如,在这种情况下,如果“便利”可能不存在,而“菜肴”的值可能是“餐馆”(在这个例子中是愚蠢的,但在另一个上下文中可能不是),那么case "restaurant"::_
将是不明确的。此外,值得注意的是,
case "restaurant"::"chinese"::_
比case List("restaurant","chinese")
的效率略高,因为后者不必要地检查在这两个元素之后没有更多的元素。2o7dmzc52#
您只需查找有问题的值,将它们放在一个元组中,然后对其进行模式匹配:
或者,您可以执行一些嵌套匹配,这可能会更简洁一些:
请注意,
map.get(key)
返回一个Option[ValueType]
(在本例中,ValueType将为字符串),因此它将返回None
,而不是在Map中不存在该键时引发异常。e0bqpujr3#
模式匹配不是您想要的。你想知道A是否完全包含B
编辑:添加匹配条件
通过这种方式,您可以轻松添加匹配条件
提供:
List(chinese restaurant, che che)
ct2axkht4#
我发现以下使用提取程序的解决方案最类似于Case类。不过,这主要是句法上的优势。
esbemjvw5#
因为,尽管我同意所有其他答案都是非常合理的,但我很感兴趣地想知道是否真的有一种方法可以使用Map进行模式匹配,我收集了以下内容。它使用与顶部答案相同的逻辑来确定匹配。
nwwlzxa76#
另一个版本要求您指定要提取的密钥,并允许您匹配这些值,如下所示: