Для понимания с двумя генераторами

Я хочу отобразить произвольное количество строк в GUI-приложении в вертикальном списке.

Рассмотрим следующий пример:

val names = Seq[String]("Boris", "Anna", "Markus", "Simone")

for(a <- 1 to names.size + 1; name <- names) yield new ListItem(
  name,
  x = 20
  y = 128 * a
  size = 128
)

Теперь, конечно, это создаст "перекрестный продукт" и напечатает:

Boris Anna Markus Simone
Boris Anna Markus Simone
Boris Anna Markus Simone
Boris Anna Markus Simone

в то время как желаемый результат будет

Boris
Anna
Markus
Simone

Но как еще я могу привязать индекс к фактической переменной? Я имею в виду, если бы я сделал счетчик, как:

for(a <- 0 to 1; b <- 0 to 1)
yield(a,b)

Я бы получил

Vector((0,0), (0,1), (1,0), (1,1))

но если бы я хотел, я мог бы (for a <- 0 to 1; b <- 0 to a) yield(a,b) и получить

Vector((0,0), (1,0), (1,1))

Я понятия не имею, как это сделать с моим примером, хотя.

1 ответ

Решение

Ты хочешь zipWithIndex, который создаст новый Seq содержащий каждый элемент из оригинала Seqв сочетании с его индексом в пределах Seq,

scala> names.zipWithIndex
res2: Seq[(String, Int)] = List((Boris,0), (Anna,1), (Markus,2), (Simone,3))

Что вы можете затем использовать:

val names = Seq[String]("Boris", "Anna", "Markus", "Simone")
class ListItem(name: String, x: Int, y: Int, size: Int)

scala> for ((name, index) <- names.zipWithIndex) 
           yield new ListItem(name, 20, 128 * index, 128)
res0: Seq[ListItem] = List(ListItem@5956b37d, ListItem@4b22015d, ListItem@2587a734, ListItem@6cf25a2b)

Который также может быть записан как map:

names.zipWithIndex.map { case (name, index) =>
    new ListItem(name, 20, 128 * index, 128)
}
Другие вопросы по тегам