首页 > 解决方案 > 折叠函数scala的不可变列表

问题描述

我创建了一个不可变列表并尝试将其折叠到一个映射中,其中每个元素都映射到一个常量字符串“abc”。我这样做是为了练习。当我这样做时,我遇到了一个错误。我不确定为什么将地图(此处为具有可变地图类型的 e1)转换为 Any。

val l = collection.immutable.List(1,2,3,4)
l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )

l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )
<console>:13: error: value += is not a member of Any
  Expression does not convert to assignment because receiver is not assignable.
       l.fold (collection.mutable.Map[Int,String]()) ( (e1,e2) => e1 += (e2,"abc") )

标签: scalafunctional-programming

解决方案


这里至少有三个不同的问题来源:

  1. Map[...]不是 的超类型Int,所以你可能想要foldLeft,而不是foldfold行为更像“香蕉括号”,它希望第一个参数表现得像某种“零”,而二元运算作为某种“加法” -这不适用于可变映射和整数)。
  2. 二元运算必须返回一些东西,包括 forfoldfoldLeft。在这种情况下,您可能希望返回修改后的地图。这就是您需要的原因; m(最后一个表达式是从闭包返回的内容)。
  3. m += (k, v)不是你想的那样。它尝试+=使用两个单独的参数调用方法。你需要的是用一对来调用它。试试m += ((k, v))吧(是的,arity 的那些问题很烦人)。

把它们放在一起:

l.foldLeft(collection.mutable.Map[Int, String]()){ (m, e) => m += ((e, "abc")); m }

但是由于您无论如何都在使用可变映射:

val l = (1 to 4).toList
val m = collection.mutable.Map[Int, String]()
for (e <- l) m(e) = "abc"

老实说,这对我来说可以说更清楚。在 afoldLeft中,我不希望地图发生突变。


推荐阅读