对于字符串列表,我这样做:
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))
对于字符串列表,我这样做:
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))
这是 的类型签名reduceLeft
:
def reduceLeft[B >: A](f: (B, A) => B): B
它要求您要减少的内容是您要减少的类型的子类型,因此在您的情况下Char
是A
并且String
不是.B
Char
您可以做一个 foldLeft 这将减少您的列表并且不需要输出是输入的子类型:
chs.foldLeft("")((x,y) => x + String.valueOf(y))
如果您只想完成结果:
scala> List('a', 'r', 'e').mkString
res0: String = are
如果你真的想学fold
s,你应该做一些更适用的事情。虽然您当然可以对字符串执行此操作,但还有更好的方法可以从字符列表创建字符串。折叠非常强大,创建一个字符串并不完全公平
例如,假设您有
case class Employee(fname:String, lname:String, age:Int)
假设您还有一个HashMap[String, List[Employee]]
按位置组织它们的方法。所以你有 25 岁的软件工程师 Joe Shmoe 和 37 岁的会计师 Larry Larison 等。你可以很容易地使用折叠将这些数据组织成扁平结构。如果您想使用它并只创建一个员工姓名列表,您可以将它与 a 结合起来flatMap
非常简单地返回 aList[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
它通过了Tuple2
ofString
和List[Employee]
。返回的_._2
第二项是与其他人一起加入Tuple2
的员工列表。flatMap
从那里,您可以使用对象foldLeft
列表Employee
来创建其名称列表。Nil
是一个空的List
(并且会List[String]
推断),那是你的起始对象。
foldLeft
接受一个应该使用元组作为参数的谓词,其中第一项将是到目前为止形成的列表,第二项将是您正在迭代的列表中的下一项。在第一次通过时,您将有一个空列表和 Joe Shmoe。
在谓词中,您创建Employee
s 名字和姓氏的字符串,并将该字符串添加到累加器li
.
这返回
List[String] = List(Harry Harrison, Larry Larrison, Joe Shmoe)
折叠是一个非常有用的工具。我发现此页面对弄清楚它们非常有帮助:http: //oldfashionedsoftware.com/2009/07/30/lots-and-lots-of-foldleft-examples/
为了展示foldLeft
和foldRight
(和map
,一路上)的工作原理,并应用了一点“真实”操作,让我们使用toChar
(of Int
):
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)
foldLeft
和的参数foldRight
是“零元素”。
我通过使用 , 使其在此处显式可见"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