我的地图列表如下
val myMap= List(
Map("name" -> "1st" , "status" -> "0"),
Map("name" -> "2nd" , "status" -> "1"),
Map("name" -> "3rd" , "status" -> "1")
)
我试图在"status" = "1"
的基础上filter
和list
,并获得另一个只有name
的List of Maps
所以输出应该是
Map("name" -> "2nd"),
Map("name" -> "3rd")
我是scala的初学者,知道我需要应用map,filter
。但不知道如何在这里进行。
如果同时执行filter
和map
,则最好的解决方案通常是使用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
。
使用filter
和map
,您可以编写如下
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)
和None
到None
。flatMap
将最终对Some
进行解包并忽略None
元素