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。主要问题不是在这种特殊情况下如何做到这一点。但是如何在更复杂的情况下避免重复,我想要检查,已经产生了什么。
答案 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))
因为理解只是语法糖,所以这里是使用map
和flatMap
产生完全相同结果的等价物
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)