我有一个“dirtyMap”,它是immutable.Map [String,collection.mutable.Set [String]]。我想将dirtyMap转换为不可变Map [String,Set [String]]。你能告诉我怎么做吗?我尝试了几种没有产生积极结果的方法
方法1:使用map函数
dirtyMap.toSeq.map(e => {
val key = e._1
val value = e._2.to[Set]
e._1 -> e._2
}).toMap()
我收到语法错误
方法2:使用foreach
dirtyMap.toSeq.foreach(e => {
val key = e._1
val value = e._2.to[Set]
e._1 -> e._2
}).toMap()
不能将map应用于foreach的输出
免责声明:如果你不知道,我是Scala noob。
更新:当我从toMap()函数中删除括号时,方法1工作。但是,以下是一个优雅的解决方案
dirtyMap.mapValues(v => v.toSet)
感谢Gabriele提供了一个很好的解释。感谢Duelist和Debojit的回答
你可以简单地做:
dirtyMap.mapValues(_.toSet)
mapValues
将该函数仅应用于Map
的值,而.toSet
将可变的Set
转换为不可变的dirtyMap
。
(我假设collection.immutable.Map
是一个toMap
。如果它是一个可变的,最后添加dirtyMap.mapValues(v => v.toSet)
)
如果你不熟悉lambdas的下划线语法,它是一个简写:
()
现在,由于toMap
,您的第一个示例无法编译。 ()
没有明确的论据,但它需要一个隐含的论证。如果您希望自动推断隐式参数,只需删除foreach
即可。
第二个例子不起作用,因为Unit
返回foreach
。这意味着foreach
执行副作用,但它不返回值。如果要对值进行链变换,请不要使用map
,而是使用flatMap
。
您可以使用
dirtoMap.map({hour(k,v)=>(k,v.toSet)})
你可以使用dirtyMap.flatMap(entry => Map[String, Set[String]](entry._1 -> entry._2.toSet)).toMap
:
map
首先,你immutable.Map(entry)
每个条目到immutable.Set
更新条目,其中值现在flatten
。你的地图看起来像这样:mutable.Map。然后mutable.Map
被调用,所以你得到immutable.Set
每个条目与dirtyMap.map(...).toMap
。然后toMap将此映射转换为不可变的。
这个变种有点复杂,你可以使用foldLeft
作为Debojit Paul提到的。
另一个变种是dirtyMap.foldLeft(Map[String, Set[String]]())(
(map, entry) => map + (entry._1 -> entry._2.toSet)
)
:
immutable.Map
您指定累加器,即foldLeft
,并使用转换后的Set将每个条目添加到此映射。
至于我,我认为使用qazxswpoi是更有效的方法。