【问题标题】:scala map - what's the best way to try a different key if a key doesn't existscala map - 如果密钥不存在,尝试不同密钥的最佳方法是什么
【发布时间】:2020-01-20 23:51:06
【问题描述】:

给定 Scala 中的一个 Map,我想尝试第一个键,如果找不到,请尝试不同的键,如果再次找不到,则返回 None。以下按预期工作:

val scores: Map[String, Int] = Map("Alice" -> 10, "Bob" -> 3)
val singleGet: Option[Int] = scores.get("NotAKey")
println(singleGet) // None
val doubleGet = scores.getOrElse("NotAKey", scores.get("NotAKeyAgain")) // works ok if no type
println(doubleGet) // None

但如果我为 doubleGet 输入一个类型,则会出错:

val doubleGet: Option[Int] = scores.getOrElse("NotAKey", scores.get("NotAKeyAgain")) // ERROR

“Any 类型的表达式不符合预期的 Option[Int] 类型”

那么最好的方法是什么?

【问题讨论】:

  • val doubleGet: Option[Int] = scores.get("NotAKey") orElse scores.get("NotAKeyAgain").
  • @LuisMiguelMejíaSuárez 啊,谢谢!你能把它作为答案让我标记它吗?

标签: scala scala-collections


【解决方案1】:

您对自己想要做什么有很好的直觉,即:
“测试一个键,如果不存在,则检查第二个”

此外,您的返回类型是正确的,因为您没有提供任何默认值,并且不能保证任何一个键都应该存在。
但是,您的问题是 scores.getOrElse("NotAKey", scores.get("NotAKeyAgain")) 将返回 Any
为什么?因为getOrElse 返回两个备选方案的 LUB (最小上限)。在这种情况下,默认值为Option[Int],但成功检索第一个键的类型为Int

您真正需要的是一种组合两个选项的方法,其中第二个用于在第一个不存在的情况下。这正是orElse 所做的。

您可以在 Map 上创建一些扩展方法,以使使用更加简单。

implicit class MapOps[K, V](private val map: Map[K, V]) extends AnyVal {
  def doubleGet(key1: K, key2: K): Option[V] =
    map.get(key1) orElse map.get(key2)

  def doubleGetOrElse[V1 >: V](key1: K, key2: K)(default: => V1): V1 =
    (map.get(key1) orElse map.get(key2)).getOrElse(default)

  def multiGet(keys: K*): Option[V] =
    keys.iterator.map(key => map.get(key)).foldLeft(Option.empty[V])(_ orElse _)

  def multiGetOrElse[V1 >: V](keys: K*)(default: => V1): V1 =
    keys.iterator.map(key => map.get(key)).foldLeft(Option.empty[V])(_ orElse _).getOrElse(default)
}

val scores: Map[String, Int] = Map("Alice" -> 10, "Bob" -> 3)
scores.doubleGet("A", "B") // res: Option[Int] = None
scores.multiGet("A", "Alice", "B") // res: Option[Int] = Some(10)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-18
    • 1970-01-01
    • 2016-11-20
    • 1970-01-01
    • 2022-11-03
    • 2021-12-17
    • 1970-01-01
    • 2011-11-18
    相关资源
    最近更新 更多