如何在功能上迭代集合组合元素?

How can I functionally iterate over a collection combining elements?

我有一个 A 类型的值序列,我想将其转换为 B 类型的序列。

某些类型为 A 的元素可以转换为 B,但是其他一些元素需要与紧邻的前一个元素组合才能生成 B。

我将其视为具有两个状态的小型状态机,第一个状态在仅需要当前 A 时处理从 A 到 B 的转换,或者在需要下一行时保存 A 并转到第二个状态;第二个状态将保存的 A 与新的 A 结合生成 B,然后返回状态 1。

我正在尝试使用 scalaz 的 Iteratees 但我担心我过于复杂了,当输入达到 EOF 时我不得不 return 一个虚拟 B。

最优雅的解决方案是什么?

试一试:

将您的列表分成两个列表。第一个是你可以直接转换的,第二个是你需要合并的。

scala> val l = List("String", 1, 4, "Hello")
l: List[Any] = List(String, 1, 4, Hello)

scala> val (string, int) = l partition { case s:String => true case _ => false}
string: List[Any] = List(String, Hello)
int: List[Any] = List(1, 4)

根据需要替换分区块中的逻辑。

获得两个列表后,您可以使用类似这样的方法对第二个列表执行任何需要的操作

scala> string ::: int.collect{case i:Integer => i}.sliding(2).collect{ 
     | case List(a, b) => a+b.toString}.toList
res4: List[Any] = List(String, Hello, 14)

您可以用您的聚合函数替换加法。

希望这对您有所帮助。

如何在序列上调用 sliding() 方法?

您可能必须在序列的开头放置一个虚拟元素,以便第一个元素(真实 开头)正确地evaluated/converted。

如果您 map() 遍历 sliding(2) 的结果,那么 map 将 "see" 每个元素及其前身。

val input:  Seq[A] = ??? // real data here (no dummy values)
val output: Seq[B] = (dummy +: input).sliding(2).flatMap(a2b).toSeq
def a2b( arg: Seq[A] ): Seq[B] = {
    // arg holds 2 elements
    // return a Seq() of zero or more elements
}