我有一个Map [String,String],并希望将这些值连接成一个字符串。
我可以看看如何使用List ...
来做到这一点scala> val l = List("te", "st", "ing", "123")
l: List[java.lang.String] = List(te, st, ing, 123)
scala> l.reduceLeft[String](_+_)
res8: String = testing123
fold *或reduce *似乎是正确的方法我无法正确获得Map的语法。
答案 0 :(得分:32)
在地图上折叠的工作方式与他们在对列表中的工作方式相同。您不能使用reduce,因为结果类型必须与元素类型(即一对)相同,但您需要一个字符串。因此,您将foldLeft
与空字符串一起用作中性元素。您也不能只使用_+_
,因为那时您会尝试将一对添加到字符串中。您必须改为使用一个函数来添加累积的字符串,该对的第一个值和该对的第二个值。所以你明白了:
scala> val m = Map("la" -> "la", "foo" -> "bar")
m: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(la -> la, foo -> bar)
scala> m.foldLeft("")( (acc, kv) => acc + kv._1 + kv._2)
res14: java.lang.String = lalafoobar
折叠的第一个参数的说明:
如您所知,函数(acc, kv) => acc + kv._1 + kv._2
有两个参数:第二个是当前正在处理的键值对。第一个是到目前为止累积的结果。但是,处理第一对时,acc
的值是多少(尚未累积结果)?当您使用reduce
时,acc
的第一个值将是列表中的第一对(并且kv的第一个值将是列表中的第二个对)。但是,如果您希望结果的类型与元素类型不同,则不起作用。因此,我们使用fold来代替reduce,我们将acc
的第一个值作为foldLeft
的第一个参数传递。
简而言之:foldLeft
的第一个参数说明了acc
的起始值应该是什么。
正如Tom指出的那样,你应该记住,地图不一定要维护插入顺序(Map2和co.do,但是hashmaps没有),所以字符串可能会以不同的顺序列出元素。你插入它们。
答案 1 :(得分:8)
这个问题已经得到了解答,但我想指出,如果你想要的话,有更简单的方法可以产生这些字符串。像这样:
scala> val l = List("te", "st", "ing", "123")
l: List[java.lang.String] = List(te, st, ing, 123)
scala> l.mkString
res0: String = testing123
scala> val m = Map(1 -> "abc", 2 -> "def", 3 -> "ghi")
m: scala.collection.immutable.Map[Int,java.lang.String] = Map((1,abc), (2,def), (3,ghi))
scala> m.values.mkString
res1: String = abcdefghi