繁体   English   中英

Scala:如何在地图中使用fold *?

[英]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的值是多少(尚未累积结果)? 当您使用reduceacc的第一个值将是列表中的第一个对象(并且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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM