[英]Scala: How do I use fold* with Map?
我有一个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的语法。
折叠在地图上的工作方式与它们在对列表上的工作方式相同。 您不能使用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
。
简而言之: foldLeft
的第一个参数说明acc
的起始值应该是什么。
正如Tom指出的那样,你应该记住,map不一定保持插入顺序(Map2和co.do,但是hashmaps没有),所以字符串可能会以不同于你插入的顺序列出元素他们。
这个问题已经得到了解答,但我想指出,如果你想要的话,有更简单的方法可以产生这些字符串。 像这样:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.