3

对于字符串列表,我这样做:

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))
4

4 回答 4

5

这是 的类型签名reduceLeft

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

它要求您要减少的内容是您要减少的类型的子类型,因此在您的情况下CharA并且String不是.BChar

您可以做一个 foldLeft 这将减少您的列表并且不需要输出是输入的子类型:

chs.foldLeft("")((x,y) => x + String.valueOf(y))
于 2013-10-18T00:58:50.050 回答
4

如果您只想完成结果:

scala> List('a', 'r', 'e').mkString
res0: String = are
于 2013-10-18T01:35:55.363 回答
1

如果你真的想学folds,你应该做一些更适用的事情。虽然您当然可以对字符串执行此操作,但还有更好的方法可以从字符列表创建字符串。折叠非常强大,创建一个字符串并不完全公平

例如,假设您有

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它通过了Tuple2ofStringList[Employee]。返回的_._2第二项是与其他人一起加入Tuple2的员工列表。flatMap

从那里,您可以使用对象foldLeft列表Employee来创建其名称列表。Nil是一个空的List(并且会List[String]推断),那是你的起始对象。

foldLeft接受一个应该使用元组作为参数的谓词,其中第一项将是到目前为止形成的列表,第二项将是您正在迭代的列表中的下一项。在第一次通过时,您将有一个空列表和 Joe Shmoe。

在谓词中,您创建Employees 名字和姓氏的字符串,并将该字符串添加到累加器li.

这返回

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

折叠是一个非常有用的工具。我发现此页面对弄清楚它们非常有帮助:http: //oldfashionedsoftware.com/2009/07/30/lots-and-lots-of-foldleft-examples/

于 2013-10-18T05:14:09.207 回答
0

为了展示foldLeftfoldRight(和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
于 2017-03-18T10:13:04.747 回答