2013-10-18 45 views
2

對於字符串列表,我這樣做:串聯字符的列表爲String通過摺疊

val l = List("a", "r", "e")      
l.reduceLeft((x, z) => x + z) 

我不知道該怎麼做了個字符的列表。以下是編譯錯誤:

val chs = List('a', 'r', 'e') 
chs.reduceLeft[String]((x,y) => String.valueOf(x) + String.valueOf(y)) 
+2

你可以只使用'mkString'! – Shadowlands

+0

我想學習如何使用褶皺。 – canadadry

+1

然後公平的。 – Shadowlands

回答

1

如果你想真正學習fold,你應該做一些更適用的事情。雖然你當然可以對字符串做這件事,但從字符列表中創建一個字符串有很多更好的方法。褶皺都非常強大,創建一個字符串並不完全做到公正

比方說,例如,你有

case class Employee(fname:String, lname:String, age:Int) 

比方說,你也有一個HashMap[String, List[Employee]],通過位置組織他們。所以你有25歲的軟件工程師Joe Shmoe和37歲的會計師Larry Larison等。你可以很容易地使用摺疊來將這些數據組織到扁平結構中。如果你想利用它,並創建只是一個員工的名字列表,你可以用flatMap結合起來非常簡單地返回List[String]

val employees = Map[String, List[Employee]]("Software Engineer" -> List(new Employee("Joe", "Shmoe", 25), new Employee("Larry", "Larrison", 37)), "Accountant" -> List(new Employee("Harry", "Harrison", 55))).flatMap(_._2).foldLeft[List[String]](Nil)((l,e) => e.fname + " " + e.lname :: l) 

employees.flatMap(_._2).foldLeft[List[String]](Nil)(
    (li,emp) => 
    s"${emp.fname} ${emp.lname}" :: li 
) 

flatMap功能爲您提供所有Employee對象的平面列表。它通過了StringList[Employee]Tuple2_._2返回作爲flatMap與其他人加入的員工名單的Tuple2的第2項。

從那裏,您可以在Employee對象的列表上使用foldLeft來創建它們的名稱列表。 Nil是一個空的List(並將推出List[String]),這是你的起始對象。

foldLeft需要一個謂詞,它應該使用一個元組作爲它的參數,其中的第一個項目將成爲迄今爲止形成的列表,第二個項目將成爲您正在迭代的列表中的下一個項目。在第一次通過時,你將有一個空列表和Joe Shmoe。

在謂詞中,您創建Employee的姓和名的字符串,並將該字符串添加到累加器li

這將返回

List[String] = List(Harry Harrison, Larry Larrison, Joe Shmoe) 

褶皺是一個非常有用的工具。我已經在盤算出來發現這個頁面是非常有幫助的:http://oldfashionedsoftware.com/2009/07/30/lots-and-lots-of-foldleft-examples/

5

下面是reduceLeft類型簽名:

def reduceLeft[B >: A](f: (B, A) => B): B 

它要求你減少是你從這樣降低類型的子類型是什麼在你的情況下CharAStringB它不是Char的子類型。

你可以做一個foldLeft這將減少你的清單,不需要輸出是輸入的子類型:

chs.foldLeft("")((x,y) => x + String.valueOf(y)) 
+0

恭喜你回答了實際問題 –

4

如果你只是想要完成的結果:

scala> List('a', 'r', 'e').mkString 
res0: String = are 
0

要與一點點展現foldLeftfoldRight運作(和map,沿途)AF應用了「真實」的操作,讓我們使用(的InttoChar

val iA: Int = 65 
val cA: Char = iA.toChar //====> A 
val cB: Char = 66.toChar //====> B 
cA + cB 
//====> 131   (Int), since char has no concatenation +, obviously 
"" + cA + cB 
//====> AB    now forced to concatenation + of String 

val li: List[Int] = List(65, 66, 67) 
li map (i => i.toChar) //====> List(A, B, C) 

foldLeftfoldRight的參數是 「零元素」。

我在此使用"0"明確可見,您希望使用""進行體面的連接。

零元素通常不應該是結果的一部分,但需要計算該結果。

下面的代碼:

i: Int因爲li: List[Int]

acc: String因爲"0"(蓄電池)

+是字符串連接

li.foldLeft("0")((acc, i) => acc + i.toChar) 
//====> 0ABC  0 --> 0A --> 0AB --> 0ABC 
li.foldLeft("0")((acc, i) => i.toChar + acc) 
//====> CBA0  0 --> A0 --> BA0 --> CBA0 

li.foldRight("0")((i, acc) => acc + i.toChar) 
//====> 0CBA  0 --> 0C --> 0CB --> 0CBA 
li.foldRight("0")((i, acc) => i.toChar + acc) 
//====> ABC0  0 --> C0 --> BC0 --> ABC0 
相關問題