2017-02-09 52 views
2

創建一個新的列表內的foreach我新手,Scala和只是想出來的東西,下面是我試圖如何在斯卡拉

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

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

scala> println(col) 
List() 

其實,我期待山坳包含A,B,C ,我錯過了什麼?

+0

將元素預先添加到列表不會修改列表。 – Jubobs

+0

我明白了,那麼在這種情況下如何修改列表? – samadhi000

回答

3

您需要在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簡單地返回由前置到col元素x的一個新的列表中的任務,原來col不會改變。您需要重新分配col到這個新生成的列表。

但是請注意,由於您使用的是副作用,因此通常不會被認爲是慣用的Scala。

+0

謝謝@ evan058,現在我的示例中的空列表對我來說是有意義的! – samadhi000

+0

@ samadhi000沒問題。就像一個供參考,[upvotes是SO的感謝貨幣](http://stackoverflow.com/help/someone-answers)。您可以提出多個您認爲有用的答案(但您只能接受一個,您爲我的帖子所做的答案)。 –

+0

我想看起來像我甚至沒有特權 – samadhi000

4

::方法在列表不添加到列表中任何東西,它創建了前面加上它的價值一個新的列表,你是放棄重新分配給col的這個新的列表來代替。 x => col = x :: col會將您列表中的每個元素添加到col。請注意,col將爲List(「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]())(_ :: _)

的下劃線給我們一個更短的語法來寫函數文本,我將離開你來決定它是否更是否清楚。

+0

感謝@puhlen的詳細解釋! – samadhi000

+0

我真的想投票,但不幸的是我沒有選擇這樣做 – samadhi000