Запросить результат для выражения внутри цикла - PullRequest
1 голос
/ 14 января 2012
for (i <- Range(1,7); j <- Range(1,7))
  yield (i,j) // want to yield only if there is no such a pair

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

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

Ответы [ 5 ]

3 голосов
/ 14 января 2012

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

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

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)))

Таким образом, только после завершения всей операции вы можете получить доступ к результату как к одной коллекции. В результате получается Vector, который расширяет 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))
2 голосов
/ 14 января 2012

Как это

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)

1 голос
/ 15 января 2012

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

Во втором случае вы можете использовать порядок и просто добавить случаи, когда a for (i <- Range(1,6); j <- Range(i+1, 7)) yield (i,j)

1 голос
/ 14 января 2012
(for {i <- (1 to 7); j <- (1 to 7)} yield (i,j)).distinct

Это вернет список кортежей без дубликатов.

И нет, в цикле for нет доступа к списку. В конце концов, это нарушит функциональное программирование.

0 голосов
/ 14 января 2012
for (i <- Range(1,7); j <- Range( i ,7))
  yield (i,j)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...