如何在Scala中的键具有特定值的地图列表中查找地图?

时间:2019-01-30 22:58:25

标签: scala functional-programming

我有一个List[Map[String, Any],我想返回其中一个键具有特定值的映射。这是一个令人困惑的例子:

val items: List[Map[String, Any]] = List(Map("name" -> "A", "size" -> 50), Map("name" -> "B", "size" -> 75), Map("name" -> "C", "size" -> 100)))

val mapB: Map[String, Any] = items.find(|m| m("name") == "B") // Psuedo code

mapB将是Map("name" -> "B", "size" -> 75)

奖励问题

是否还有一种方法可以返回另一个键的值,而不是整个Map的值?

例如,如果我只想要size name的{​​{1}}值(75)?我知道我可以通过两步操作从B中提取它,但是如果还有另一种惯用的方式,我会对学习它感兴趣。

谢谢!

2 个答案:

答案 0 :(得分:2)

PUT event { "settings": { "keyspace": "my_keyspace" }, "mapping": { "_doc": { "discover": ".*" } } } 返回find(),以防找不到所需的内容。

Option

val mapB: Option[Map[String, Any]] = items.find(_("name") == "B") //safe

要从第一个val mapB: Map[String, Any] = items.find(_("name") == "B").get //unsafe, might throw (其中size)中提取Map的值,您可以执行以下操作。

"name" -> "B"

请注意,val sz :Any = items.find(m => m.get("name").contains("B") && m.get("size").nonEmpty).fold(0:Any)(_("size")) 的类型为sz,因为这就是Any值的类型。这意味着您必须先对其进行转换(不建议使用)以键入Map,然后才能对其进行任何有用的操作。

避免输入Int。这肯定表明您走错了方向。

答案 1 :(得分:1)

补充jwvh的答案(并使用Tim的建议来提高安全性)
这是一个解决您的红利问题的函数。

def findAndGet(maps: List[Map[String, Any]], condition: (String, Any), key: String): Option[Any] = condition match {
  case (k, v) =>
    maps.find(map => map.get(k).contains(v)).flatMap(map => map.get(key))
}
findAndGet(maps = items, condition = ("name", "B"), key = "size")
// res0: Option[Any] = Some(75)

BTW,Map[String, Any]使您正在处理 JSON 的事情,让您看看任何Scala库如何以更“类型安全”的方式处理它们“方法?”,在代码中添加Any始终应该是对某些错误的警告