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

Scala 如何在功能上迭代组合元素的集合?,scala,functional-programming,scalaz,Scala,Functional Programming,Scalaz,我有一个a类型的值序列,我想把它转换成B类型的序列 类型为A的某些元素可以转换为B,但是其他一些元素需要与前一个元素组合以生成B 我将其视为一个具有两种状态的小型状态机,第一种状态机在只需要当前a时处理从a到B的转换,或者在需要下一行时保存a并进入第二种状态;第二种状态将保存的A与新的A结合起来生成B,然后返回到状态1 我试图使用scalaz的Iteratees,但我担心这会使它过于复杂,当输入达到EOF时,我被迫返回一个伪B 最优雅的解决方案是什么?试一试: 将列表划分为两个列表。第一个是可以

我有一个a类型的值序列,我想把它转换成B类型的序列

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

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

我试图使用scalaz的
Iteratee
s,但我担心这会使它过于复杂,当输入达到EOF时,我被迫返回一个伪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)
您可以用聚合函数中的任何函数替换加法


希望这会有所帮助。

在序列上调用
slideing()
方法怎么样

您可能必须在序列的头部放置一个虚拟元素,以便正确计算/转换第一个元素(真实头部)

如果对滑动(2)的结果执行
map()
操作,则map将“查看”每个元素及其前一个元素

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
}

您如何判断哪些需要上一个元素?如果第一个元素需要上一个元素,你会怎么做?>然而,
coll.slideing(2).map{case(pre,cur)=>if(needsPrevious(cur)combine(pre,cur)else convert(cur)}
看起来很简单,尽管我在当前实现中编写问题时有点不精确;实际上,我需要的不仅仅是上一个元素,而是下一个元素。也就是说,在每次迭代中,我可以转换,或者我知道我还需要下一个元素来进行转换。与
slidi的想法相同ng(2)
仍然有效。这会给你当前和下一个,或者上一个和当前。它们实际上是一样的(两个相邻的元素,你只需要选择哪个是当前的)。
coll.slideing(2).map{case(cur,nxt)=>if(needsNext(cur)combine(cur,nxt)else convert(cur)}
我将尝试这种方式;我真正想要避免的是添加虚拟元素。如果您的第一个(或最后一个,问题在您的注释中进行了修改)需要与“其他”元素结合,那么虚拟元素是最简单的解决方案。为什么要避免它?我添加了代码来说明这个概念。并不是每次调用
a2b()
需要生成一个有意义的数据元素。事实上,这正是我所要寻找的。我没有想到要让我的转换函数返回一个集合和flatMap()。