如何在scala中的foreach中创建一个新列表

时间:2017-02-09 20:42:03

标签: scala

我是scala的新手,只是尝试了一些东西,下面是我正在尝试的事情

scala> var col  = List[String]()
col: List[String] = List()

scala> List("a", "b", "c").foreach(x => x :: col)

scala> println(col)
List()

实际上,我期待col包含a,b,c,我错过了什么?

2 个答案:

答案 0 :(得分:6)

您需要foreach

中的作业
scala> var col  = List[String]()
col: List[String] = List()

scala> List("a", "b", "c").foreach(x => {col = x :: col})

scala> col
res0: List[String] = List(c, b, a)

操作x :: col只返回一个新列表,其中包含x前面的元素col,原始col不会更改。您需要将col重新分配给此新生成的列表。

但请注意,由于您使用的是副作用,因此通常不会将其视为惯用的Scala。

答案 1 :(得分:6)

列表中的::方法不会向列表中添加任何内容,它会创建一个包含前置值的新列表,您将丢弃此新列表,而不是将其重新分配给colx => col = x :: col会将您列表中的每个元素添加到col。请注意,col将为列表(“c”,“b”,“a”),订单相反,因为您要将元素预先挂起到col

请注意foreach不返回任何内容,专为副作用操作而设计。如果您只是想将一个集合转换或将元素加载到另一个集合中,那么可以使用更好的方法。

对于您的特定操作,最合适的方法是foldRight,它以相反的顺序(从右到左)迭代元素。我们希望在此反向迭代,因为当您将元素一次添加到列表中时,订单会反转。

val col = List("a", "b", "c").foldRight(List[String]())((x, acc) => x :: acc)将生成List("a", "b", "c")。这样做的好处是我们不再需要使用var来声明一个可变变量,事实上我们不会 需要提前声明我们的清单。

请注意,我们可以使用一些特殊语法来保存一些输入

val col = List("a", "b", "c").foldRight(List[String]())(_ :: _)

下划线为我们提供了更短的语法来编写函数文字,我将由您决定是否更清楚。