我正在寻找一种方法来增加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中运行并在第一次增量结束时停止。
答案 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
条件。)
剩下的只是一个语法糖,用于将压缩元组与i
和j
变量进行匹配。
答案 1 :(得分:0)
使用for comprehension
无法做到这一点,因为for comprehension
会转换为map
,flatMap
和filter
来电。 for comprehension
内的表达式被包装/嵌套在map
,flatMap
内,因此嵌套是不可避免的。
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))