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 для відповіді № 1Ви не можете отримати доступ до членів незмінної колекції, побудованої зсередини для розуміння.
Перш за все, я можу змінити ваш приклад, щоб він фактично створював дублікати:
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))
2 для відповіді № 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)
?
1 для відповіді № 3
(for {i <- (1 to 7); j <- (1 to 7)} yield (i,j)).distinct
Це б повернуло список кортежів без дублікатів.
І ні, немає жодного способу отримати доступ до списку всередині for
петля. Це врешті-решт порушить функціональне програмування.
1 для відповіді № 4
Я не впевнений, чи хочете ви запобігти парам однакових записів або однакових пар, ігноруючи які на першому місці.
У другому випадку ви можете використовувати замовлення та просто додати випадки, коли a <b або a <= b:
for (i <- Range(1,6); j <- Range(i+1, 7)) yield (i,j)
-1 для відповіді № 5
for (i <- Range(1,7); j <- Range( i ,7))
yield (i,j)