用于迭代的Scala函数代码,其值转发到下一次迭代

时间:2015-05-07 11:28:07

标签: scala

如何使此代码更具功能性,其中当前迭代的值保留到下一个(变量last),

def f(i: Int): Int = ???

var last = -1

for (v <- xs) yield {
  val start = f(v)
  val end = f(start)

  val res = if (last == start - 2) "abc" else "xyz"

  last = end
  res
}

2 个答案:

答案 0 :(得分:3)

我认为foldLeft应该有效。您可以传递下一次迭代中所需的值,并将结果传递给元组

   val list = (1 to 10 by 2)                       
   //> list  : scala.collection.immutable.Range = Range(1, 3, 5, 7, 9)
   val last = -1
   list.foldLeft((last, List[String]())) {
     case (r, c) => println(s"Current - $c last - ${r._1}")
     (c, r._2 :+ if (...) "abc" else "xyz")
     // c will be the value that you need to pass to the next iteration
     // r._2 will contain the list which you would have got with your for comprehension 
   }
  //> Current - 1 last - -1
  //| Current - 3 last - 1
  //| Current - 5 last - 3
  //| Current - 7 last - 5
  //| Current - 9 last - 7

答案 1 :(得分:0)

使用scanLeft注意到这种方法(受@ {hhit方法使用foldLeft启发),此处为startend的预处理对集合,即实例

val a = Array((1,2), (3,4), (5,6))

接下来,假设s代表starte代表end,所以

a.scanLeft((-1,-1,-1)) { case(acc, (s,e)) => (s,e,acc._2) }.drop(1)

生成包含startendlast的三元组,

Array((1,2,-1), (3,4,2), (5,6,4))

我们可以应用if-else表达式;共,

a.scanLeft((-1,-1,-1)) { case(acc, (s,e)) => (s,e,acc._2) }.
  drop(1).
  map(t => if (t._3 == t._1 - 2) "abc" else "xyz")