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

是否有可能訪問循環內由yield生成的列表? 例如,如果我不想添加重複項。查詢循環內部for表達式的結果

P.S.主要問題不在於如何在這種特殊情況下做到這一點。但是,如何在更復雜的情況下避免重複,我想檢查什麼已經放棄。

回答

3

您無法從for理解中訪問正在構建的不可變集合的成員。

首先,我要修改你的榜樣,因此實際產生重複:

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產生完全相同的結果相當於你可以看到,你實際上沒有建立一個單一的集合,而是一個集合集合,然後在它們創建時將它們合併在一起。內部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)]一個矢量,所以你可以使用任何的該性狀的方法對結果,其中之一是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
(for {i <- (1 to 7); j <- (1 to 7)} yield (i,j)).distinct 

這將返回沒有重複的元組列表。

不,沒有辦法訪問for循環內的列表。畢竟,這將破壞函數式編程。

+0

感謝。你能解釋我可以在收益率上應用哪些功能嗎?如果你申請不同的產品,那麼產量代表一個清單? – damluar 2012-01-14 18:21:07

+0

@damluar我認爲你誤解了「收益」的含義。請參閱http:// stackoverflow。com/questions/1052476/can-someone-explain-scalas-yield – 2012-01-14 23:36:46

+0

不,我理解它是正確的。我只是沒有注意到括號。 – damluar 2012-01-15 00:16:35

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) 

+0

主要問題不是在這種特殊情況下如何去做。但是,如何在更復雜的情況下避免重複,我想檢查什麼已經放棄。 – damluar 2012-01-14 18:22:39

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

我不知道,你是否要阻止對同文條目,或者是同性戀雙方,無視其中的第一個。

在第二種情況下,你可以使用一個排序,並且只需添加情況下,一個< B或A < = B:

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