通过折叠将Char列表连接成String

时间:2013-10-18 00:51:59

标签: scala

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

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

4 个答案:

答案 0 :(得分:5)

以下是reduceLeft的类型签名:

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

要求您减少的内容是您正在减少的类型的子类型,因此Char A StringB 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 StringList[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)

要显示foldLeftfoldRight(以及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"是字符串连接

+