2017-09-01 39 views
0

在斯卡拉,如果我有一个嵌套的for循环,我想在每一个执行不同的事情。如何在scala中仅执行outer for循环?

for (int i = 0; i<5; i++) { 
    System.out.println(i);  //do something for just i 
    for(int j = 0; j<5; j++) { 
     System.out.println(i+j); //do something for both i and j 
    } 
} 

但Scala代码:

for {i<-0 to 5 
    j<- 0 to 5} yield { print(i); print(i+j)} 

给出了输出:

0 
(0,0) 
0 
(0,1) 
0 
(0,2) 
0 
(0,3) 
0 
(0,4) 
0 
(0,5) 

,但我希望它是:

0 
(0,0) 
(0,1) 
(0,2) 
(0,3) 
(0,4) 
(0,5) 

有没有办法,只每打印和i+j每个ijONE for循环?

+0

'如果(j == 0)打印(我);打印(i + j);'..不太干净,作为副作用。为什么不只是一个嵌套循环?您仍然可以使用该范围的“x < - a to b”语法。 – user2864740

+0

这是我的问题的抽象表示。基本上我想遍历两件事,在外层循环和内层循环中做一些事情。@ user2864740 – rileyss

+2

只需使用两个for-loops。另外,'for {...} {...}'是for-loop。 '{...} yield {...}'是理解。他们是非常不同的东西。 –

回答

1

做着同样是使用map功能的替代方式如下

val loop = 0 to 5 
loop.map(i => { 
    println(i) // do your stuffs as you did for i 
    loop.map(j => { 
    println(i, j) //do your stuffs as you did for i, j 
    }) 
}) 
3

编译器重写for推导成它们的组成map()flatMap()foreach(),和withFilter()份。这就是为什么一些Scala语法的正常规则不适用于序列理解表达式中的原因。他们在重写过程中受到重创。

有一些技巧来解决这个问题。

for { 
    i <- 0 to 5 
    _ = println(i) 
    j <- 0 to 5 
} yield // do stuff with i and j 

这真的取决于你需要与i值做什么。这可能是因为for理解不是这项工作的最佳工具。

+0

如果是出于副作用,就像OP的情况一样,删除yield可能会更好。 –

+0

@ user2864740;我写了“一些正常规则”不适用。这里有两个例子:1)不能放置'println()'语句(没有上述答案中显示的技巧)。 2)不能以正常方式创建变量。 (例如,'val x = 5'不会编译,但是'x = 5'会)我不是想说OP的代码不会执行。它工作得很好。但是,OP想要做什么,在两台发电机之间放置代码,充其量是棘手的,很少是可取的。 – jwvh

1

我认为这将这样的伎俩:

(0 to 5).zip(0 to 5).foreach{case (i, j) => 
    //do stuff to i an dj 
} 
+0

如果“stuff”是print(i),它与原始文件具有相同的“问题”;打印(I + J)'。 – user2864740