对于字符串列表,我这样做:
val l = List("a", "r", "e")
l.reduceLeft((x, z) => x + z)
我不知道如何为Chars列表做这件事。以下是编译错误:
val chs = List('a', 'r', 'e')
chs.reduceLeft[String]( (x,y) => String.valueOf(x) + String.valueOf(y))
答案 0 :(得分:5)
以下是reduceLeft
的类型签名:
def reduceLeft[B >: A](f: (B, A) => B): B
要求您减少的内容是您正在减少的类型的子类型,因此Char
A
String
为B
Char
1}}这不是chs.foldLeft("")((x,y) => x + String.valueOf(y))
的子类型。
你可以做一个foldLeft,它会减少你的列表并且不要求输出是输入的子类型:
{{1}}
答案 1 :(得分:4)
如果您只想完成结果:
scala> List('a', 'r', 'e').mkString
res0: String = are
答案 2 :(得分: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
个对象的平面列表。它传递了Tuple2
String
和List[Employee]
。 _._2
返回Tuple2
的第二项,即flatMap
与其他人一起加入的员工列表。
从那里,您可以在foldLeft
对象列表中使用Employee
来创建其名称列表。 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/
答案 3 :(得分:0)
要显示foldLeft
和foldRight
(以及map
的工作方式),稍加一点“真实”操作,让我们使用{{1} }(toChar
):
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"
是字符串连接
+