Scala在for循环中递增多个变量

时间:2016-09-15 10:00:04

标签: scala

我正在寻找一种方法来增加for循环中的两个变量,就像在Java中完成一样:

for (int j = column + 1, i = row + 1; j < size && i < size; j++, i++) 

如果我写的话在Scala中

for(j <- start to end; i <- start2 to end2)

这会转换为嵌套循环,但我需要它在raw中运行并在第一次增量结束时停止。

2 个答案:

答案 0 :(得分:3)

你可以这样写:

val column = 5; val row = 3; val size = 10; // some input..

for {
  (i, j) <- (row + 1 to size - 1) zip (column + 1 to size - 1)
} {
  println(s"i=$i j=$j")
}

/* prints:
i=4 j=6
i=5 j=7
i=6 j=8
i=7 j=9
*/

诀窍是,您不希望拥有for { i <- ... ; j <- ... }i的所有组合(j)。相反,你希望它们一起增加。

因此,您可以使用另一个范围创建一个范围(start to end)zip。 (该操作将删除较长序列的尾部 - 这基本上确保了j < size && i < size条件。)

剩下的只是一个语法糖,用于将压缩元组与ij变量进行匹配。

答案 1 :(得分:0)

使用for comprehension无法做到这一点,因为for comprehension会转换为mapflatMapfilter来电。 for comprehension内的表达式被包装/嵌套在mapflatMap内,因此嵌套是不可避免的。

for {
 i <- 1 to 10
 j <- 20 to 30
} yield (i -> j)

变为

(1 to 10).flatMap { i =>
  (20 to 30).map { j =>
     (i -> j)
  }
}

所以嵌套是不可避免的。

但如果我和j在同一点开始和结束,我们可以做类似下面的事情

i增加时,只需指定j = i。请注意,j不会独立于i而增加,但至少您不会嵌套。

for {
  i <- 1 to 10
  j = i if j < 5
} yield i -> j

Scala REPL

scala> for {
        i <- 1 to 10
        j = i if j < 5
       } yield i -> j
res3: collection.immutable.IndexedSeq[(Int, Int)] = Vector((1, 1), (2, 2), (3, 3), (4, 4))