查询循环内表达式的结果

时间:2012-01-14 17:46:51

标签: scala

for (i <- Range(1,7); j <- Range(1,7))
  yield (i,j) // want to yield only if there is no such a pair

是否可以在循环内访问由yield组成的列表? 例如,如果我不想添加重复项。

P.S。主要问题不是在这种特殊情况下如何做到这一点。但是如何在更复杂的情况下避免重复,我想要检查,已经产生了什么。

5 个答案:

答案 0 :(得分:3)

您无法访问从for comprehension中构建的不可变集合的成员。

首先,我要修改你的例子,以便它实际上产生重复:

for (i <- Range(1,3); j <- Range(1,3)) yield (i min j, i max j)
//scala.collection.immutable.IndexedSeq[(Int, Int)] = Vector((1,1), (1,2), (1,2), (2,2))

因为理解只是语法糖,所以这里是使用mapflatMap产生完全相同结果的等价物

Range(1,3).flatMap{i => Range(1,3).map{ j => (i min j, i max j)}}

正如您所看到的,您实际上并不是在构建单个集合,而是构建集合,然后在创建它们时将它们合并在一起。内部map将每个j放在范围内并将其映射到一对,然后外部flatMap将每个i映射到一系列对并将它们合并在一起。如果我将flatMap更改为map,则结果如下:

Range(1,3).map{i => Range(1,3).map{ j => (i min j, i max j)}}
//Vector(Vector((1,1), (1,2)), Vector((1,2), (2,2)))

因此,只有在整个操作完成后才能将结果作为单个集合访问。结果是一个扩展IndexedSeq[(Int, Int)]的Vector,所以你可以在结果上使用任何特征的方法,其中一个是distinct

(for (i <- Range(1,3); j <- Range(1,3)) yield (i min j, i max j)).distinct
//Vector((1,1), (1,2), (2,2))

答案 1 :(得分:2)

喜欢这个

for (i <- Range(1,7); j <- Range(1,7); if i != j ) yield (i,j)

或者

for (i <- Range(1,7); j <- Range(1,7); if i < j ) yield (i,j)

答案 2 :(得分:1)

(for {i <- (1 to 7); j <- (1 to 7)} yield (i,j)).distinct

这将返回没有重复的元组列表。

不,没有办法访问for循环内的列表。毕竟,这会打破函数式编程。

答案 3 :(得分:1)

我不确定,你是想要阻止成对的条目,还是想要的对,忽略哪个首先出现。

在第二种情况下,您可以使用排序,只需添加一个&lt; b或a&lt; = b:

for (i <- Range(1,6); j <- Range(i+1, 7)) yield (i,j)

答案 4 :(得分:-1)

for (i <- Range(1,7); j <- Range( i ,7))
  yield (i,j)