将Scala中可变字符串集的映射转换为不可变字符串集的映射
我有一个不可变的“dirtyMap”。Map[String,collection.mutable.Set[String]]。我想将dirtyMap转换为不可变映射[String,Set[String]]。你能告诉我怎么做吗。我尝试了两种没有产生积极效果的方法 方法1:使用映射函数将Scala中可变字符串集的映射转换为不可变字符串集的映射,scala,scala-collections,Scala,Scala Collections,我有一个不可变的“dirtyMap”。Map[String,collection.mutable.Set[String]]。我想将dirtyMap转换为不可变映射[String,Set[String]]。你能告诉我怎么做吗。我尝试了两种没有产生积极效果的方法 方法1:使用映射函数 dirtyMap.toSeq.map(e => { val key = e._1 val value = e._2.to[Set] e._1 -> e._2 }).toMap() 我发现语法错
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()
无法将toMap应用于foreach的输出
免责声明:如果你说不出来,我就是Scala noob
更新:当我从toMap()函数中删除括号时,方法1起作用。然而,下面是一个优雅的解决方案
dirtyMap.mapValues(v => v.toSet)
谢谢Gabriele为我们提供了一个很好的解释。感谢Duelist和Debojit的回答您可以使用
平面地图
:
dirtyMap.flatMap(entry => Map[String, Set[String]](entry._1 -> entry._2.toSet)).toMap
首先,将map
每个条目映射到不可变。使用更新的条目映射(条目)
,其中值为不可变。立即设置。您的地图如下所示:mutable.map。
然后调用flatten
,这样就可以得到mutable.Map
,每个条目都带有不可变的.Set
。然后toMap将此映射转换为不可变
这个变体有点复杂,您只需使用Debojit Paul提到的dirtyMap.map(…).toMap
另一个变体是foldLeft
:
dirtyMap.foldLeft(Map[String, Set[String]]())(
(map, entry) => map + (entry._1 -> entry._2.toSet)
)
指定累加器,该累加器是不可变的。映射
,并使用转换的集合将每个条目添加到此映射
对我来说,我认为使用foldLeft是更有效的方法。你可以使用
dirtyMap.map({case(k,v)=>(k,v.toSet)})您可以简单地执行以下操作:
dirtyMap.mapValues(_.toSet)
mapValues
将只对Map
的值应用该函数,并且.toSet
将可变的集合
转换为不可变的
(我假设dirtyMap
是一个集合。不可变的.Map
。如果它是可变的,只需在最后添加toMap
)
如果您不熟悉lambdas的下划线语法,它是以下内容的简写:
dirtyMap.mapValues(v => v.toSet)
现在,由于
()
,您的第一个示例无法编译toMap
不接受显式参数,但接受隐式参数。如果希望自动推断隐式参数,只需删除()
第二个示例不起作用,因为
foreach
返回Unit
。这意味着foreach
执行副作用,但不返回值。如果要在值上链接转换,请不要使用foreach
,而是使用map
。它仍然返回mutable.map
toMap
是必需的scala>dirtyMap.map({case(k,v)=>(k,v.toSet)})res2:scala.collection.immutable.map[String,scala.collection.immutable.Set[String]=map(a->Set(3,1,2),b->Set(3,1,2))
你确定你的dirtyMap
是不可变的
吗?尝试执行我不知道你为什么说它将返回可变映射。请共享您的输出scala>val dirtyMap=new mutable.HashMap[String,collection.mutable.Set[String]()dirtyMap:scala.collection.mutable.HashMap[String,scala.collection.mutable.Set[String]=Map()scala>dirtyMap更新(“test1”,collection.mutable.Set(“test11”,“test12”))scala>dirtyMap更新(“test2”,collection.mutable.Set(“test21”、“test22”))scala>dirtyMap.map({case(k,v)=>(k,v.toSet)})res2:scala.collection.mutable.HashMap[String,scala.collection.immutable.Set[String]=map(test2->Set(test21,test22),test1->Set(test12,test11))
在方法1中删除toMap
后的括号可以帮助消除语法错误。