/ / Запит результату для вираження всередині циклу - scala

Запитувати результат для вираження всередині циклу - скала

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)