scala map 通过键获取值,键不区分大小写

use*_*587 3 scala hashmap

我有一个 Map[String, Info] 的地图,它包含可以是大写或小写的键,如下所示:

person1: PersonInfo1
person2: PersonInfo2
PERSON1: PersonInfo1
Run Code Online (Sandbox Code Playgroud)

我想获取键“person1”的值,如果没有找到,我将尝试使用“PERSON1”键,我尝试了以下代码:

val info = map.get(key) match {
  case Some(personInfo) => personInfo
  case None =>
    map.get(key.toUpperCase()) match {
      case Some(personInfo) => personInfo
      case None             => None
    }
}
Run Code Online (Sandbox Code Playgroud)

但是此返回信息作为具有可序列化的产品类型,我如何将信息作为 PersonInfo 类型返回?Scala 中有没有一种方法可以让我通过键从映射中获取值并忽略键的大小写?

Gáb*_*kos 6

有用于排序地图的比较器,允许不区分大小写地从地图中获取。示例:https : //scastie.scala-lang.org/PfHTh16CROag7PNrknx1sQ

val map = scala.collection.immutable.SortedMap("key1" -> 45, "Key2" -> 43, "KEY3" -> 42)(scala.math.Ordering.comparatorToOrdering(String.CASE_INSENSITIVE_ORDER))
map.get("key1") // Some(45)
map.get("key2") // Some(43)
map.get("key3") // Some(42)
map.get("key4") // None
Run Code Online (Sandbox Code Playgroud)

如果您在所有情况下都返回 Options,则可以解决您的实际问题,例如:

      val info = map.get(key) match {
        case somePi@Some(personInfo) => somePi
        case None => map.get(key.toUpperCase()) match {
          case Some(personInfo) => Some(personInfo)
          case None => None
        }
      }
Run Code Online (Sandbox Code Playgroud)

请注意somePi@ => somePi引用表达式或 的部分Some(personInfo)

也许值得说明的是,为什么你得到这个错误消息。我假设personInfo是一个case class实现Productand Serializable,就像None. 它们的常见类型是Product with Serializable.


Krz*_*sik 6

你可以用orElse. 我会为此创建一个扩展方法:

implicit class CaseInsensitiveGetMap[V] (m: Map[String,V]) {
   def iget (key: String): Option[V] = m.get(key)
      .orElse(m.get(key.toUpperCase())) //you can add more orElse in chain
}
Run Code Online (Sandbox Code Playgroud)

然后你可以像这样使用它:

map.iget("person2")
Run Code Online (Sandbox Code Playgroud)