将可变字符串集的映射转换为Scala中不可变字符串集的映射

问题描述 投票:0回答:3

我有一个“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的回答

scala scala-collections
3个回答
1
投票

你可以简单地做:

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


0
投票

您可以使用

dirtoMap.map({hour(k,v)=>(k,v.toSet)})


0
投票

你可以使用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是更有效的方法。

© www.soinside.com 2019 - 2024. All rights reserved.