如何在Scala中过滤映射列表



我的地图列表如下

val myMap=  List(
Map("name" -> "1st" , "status" -> "0"),
Map("name" -> "2nd" , "status" -> "1"),
Map("name" -> "3rd" , "status" -> "1")
)

我试图在"status" = "1"的基础上filterlist,并获得另一个只有nameList of Maps

所以输出应该是

Map("name" -> "2nd"),
Map("name" -> "3rd")

我是scala的初学者,知道我需要应用map,filter。但不知道如何在这里进行。

如果同时执行filtermap,则最好的解决方案通常是使用collect:

myMap.collect{ case m if m.get("status").contains("1") => m - "status" }

考虑将filter&map转换为collect:

val myMap = List(
Map("name" -> "1st", "status" -> "0"),
Map("name" -> "2nd", "status" -> "1"),
Map("name" -> "3rd", "status" -> "1"),
Map("xx" -> "4th",   "status" -> "1"),
Map("name" -> "5th", "yy" -> "1")
)
myMap.collect{ case m if m.get("status").contains("1") && m.get("name").nonEmpty =>
Map("name" -> m("name"))
}
// List(Map(name -> 2nd), Map(name -> 3rd))

collect中的保护子句确保只包括那些由键值status->1和密钥name组成的Map

使用filtermap,您可以编写如下

myMap
.filter(m => m.get("status") == Some("1")) // filter maps with status 1
.map(m => "name" -> m.get("name").get)     // use the name attribute to create a new map

注意,get方法返回Option,因为请求的密钥可能不存在。因此,您需要与Some("1")进行比较,并在m.get("name")的结果上使用.get。在不检查选项是否为空的情况下使用.get方法不是一种好的风格,因为如果映射不包含name键,则这将在运行时失败。从结果中省略这些地图的更好方法可能是

myMap
.filter(m => m.get("status") == Some("1"))
.flatMap(m => m.get("name").map(n => "name" -> n))

这里使用的映射来自Option类,并将找到的名称映射到Some("name" -> n)NoneNoneflatMap将最终对Some进行解包并忽略None元素

最新更新