2012-01-14 2 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 

Возможно ли иметь доступ к списку, образованному выходом, внутри цикла? Например, если я не хочу добавлять дубликаты.Запросить результат для выражения внутри цикла

P.S. Главный вопрос заключается не в том, как это сделать в этом конкретном случае. Но как избежать дубликатов в более сложном случае, где я хочу проверить, что уже было сделано.

ответ

3

Вы не можете получить доступ к элементам неизменяемой коллекции, которая строится изнутри для понимания.

Прежде всего, я собираюсь изменить свой пример, так что на самом деле производит дубликаты:

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)], так что вы можете использовать любого из методов этой черты на результате, один из них 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

спасибо. можете ли вы объяснить, какие функции я могу применить по доходности. Если вы применяете различные, то yield представляет список? – damluar

+0

@damluar Я думаю, вы неправильно поняли, что означает «выход». См. Http: // stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield –

+0

Нет, я понимаю это правильно. Я просто не замечал, чтобы скобки окружали. – damluar

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

1

Я не уверен, хотите ли вы, чтобы предотвратить пары тождественного записей , или идентичные пары, игнорируя, что на первом месте.

Во втором случае, вы можете использовать порядок, и просто добавить случаи, когда < б или < = Ь:

for (i <- Range(1,6); j <- Range(i+1, 7)) yield (i,j) 
Смежные вопросы