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

时间:2018-06-15 04:57:12

标签: scala scala-collections

我有一个" dirtyMap"这是immutable.Map [String,collection.mutable.Set [String]]。我想将dirtyMap转换为不可变Map [String,Set [String]]。你能告诉我怎么做吗?我尝试了几种没有产生积极结果的方法

方法1:使用地图功能

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()

无法将地图应用于foreach的输出

免责声明:如果你不能告诉我,我是Scala noob。

更新:当我从toMap()函数中删除括号时,方法1有效。但是,以下是一个优雅的解决方案

dirtyMap.mapValues(v => v.toSet)

感谢Gabriele提供了一个很好的解释。感谢Duelist和Debojit的回答

3 个答案:

答案 0 :(得分:1)

您可以这样做:

dirtyMap.mapValues(_.toSet)

mapValues会将该函数仅应用于Map的值,而.toSet会将可变Set转换为不可变的值。{/ p>

(我假设dirtyMapcollection.immutable.Map。如果它是可变的,只需在最后添加toMap

如果你不熟悉lambdas的下划线语法,那么它是一个简写:

dirtyMap.mapValues(v => v.toSet)

现在,由于(),您的第一个示例无法编译。 toMap没有明确的参数,但它需要一个隐含的参数。如果您希望自动推断隐式参数,只需删除()

第二个示例不起作用,因为foreach返回Unit。这意味着foreach执行副作用,但它不返回值。如果您想对值进行变换,请不要使用foreach,而是使用map

答案 1 :(得分:0)

您可以使用flatMap

dirtyMap.flatMap(entry => Map[String, Set[String]](entry._1 -> entry._2.toSet)).toMap

首先,您map每个条目immutable.Map(entry)都有更新的条目,其值现在为immutable.Set。你的地图看起来像这样:mutable.Map。 然后调用flatten,因此每个条目mutable.Map都会获得immutable.Set。然后toMap将此映射转换为不可变的。

这个版本有点复杂,你只需使用dirtyMap.map(...).toMap作为Debojit Paul提到的。

另一个变体是foldLeft

dirtyMap.foldLeft(Map[String, Set[String]]())(
  (map, entry) => map + (entry._1 -> entry._2.toSet)
)

指定累加器,即immutable.Map,并使用转换后的Set将每个条目添加到此地图。

至于我,我认为使用foldLeft是更有效的方式。

答案 2 :(得分:0)

您可以使用

dirtyMap.map({case(k,v)=>(k,v.toSet)})