Пример:
val l = List(1,2,3)
val t = List(-1,-2,-3)
Могу ли я сделать что-то вроде этого?
for (i <- 0 to 10) yield (l(i)) yield (t(i))
В основном я хочу дать несколько результатов для каждой итерации.
Пример:
val l = List(1,2,3)
val t = List(-1,-2,-3)
Могу ли я сделать что-то вроде этого?
for (i <- 0 to 10) yield (l(i)) yield (t(i))
В основном я хочу дать несколько результатов для каждой итерации.
Непонятно, о чем вы просите - что вы ожидаете от семантики множественного урона. Однако одна вещь заключается в том, что вы, вероятно, никогда не хотите использовать индексы для навигации по списку - каждый вызов t (i) выполняется O (i).
Итак, вот одна возможность, которую вы могли бы просить
scala> val l = List(1,2,3); val t = List(-1,-2,-3)
l: List[Int] = List(1, 2, 3)
t: List[Int] = List(-1, -2, -3)
scala> val pairs = l zip t
pairs: List[(Int, Int)] = List((1,-1), (2,-2), (3,-3))
И вот еще одна возможность, которую вы можете просить
scala> val crossProduct = for (x <- l; y <- t) yield (x,y)
crossProduct: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3))
Позднее это всего лишь синтаксический сахар для
scala> val crossProduct2 = l flatMap {x => t map {y => (x,y)}}
crossProduct2: List[(Int, Int)] = List((1,-1), (1,-2), (1,-3), (2,-1), (2,-2), (2,-3), (3,-1), (3,-2), (3,-3))
Третья возможность заключается в том, что вы хотите чередовать их
scala> val interleaved = for ((x,y) <- l zip t; r <- List(x,y)) yield r
interleaved: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10)
Этот синтаксический сахар для
scala> val interleaved2 = l zip t flatMap {case (x,y) => List(x,y)}
interleaved2: List[Int] = List(1, -1, 2, -2, 3, -3, 4, -4, 5, -5, 6, -6, 7, -7, 8, -8, 9, -9, 10, -10)
Нет, вы не можете использовать множественные предложения, но есть обход. Например:
for (i <- 0 to 10;
r <- List(l(i), t(i)))
yield r
Конечно, вы можете встраивать для-понятий, но это приведет к списку списков элементов, который, как я считаю, не является тем, что вы хотите.
Урожайность может быть вложенной, что приведет к...
for (i <- 0 to 3) yield {
for (j <- 0 to 2) yield (i,j)
}
в векторе Vector:
scala.collection.immutable.IndexedSeq[scala.collection.immutable.IndexedSeq[(Int, Int)]]
= Vector(Vector((0,0), (0,1), (0,2)), Vector((1,0), (1,1), (1,2)), Vector((2,0), (2,1), (2,2)), Vector((3,0), (3,1), (3,2)))
for (i <- 0 to 3;
j <- 0 to 2) yield (i,j)
Сплюснутое решение семантически отличается.
Вот агностическое решение типа для неизвестного, меняющегося количества элементов в неизвестном числе списков:
def xproduct (xx: List [List[_]]) : List [List[_]] =
xx match {
case aa :: bb :: Nil =>
aa.map (a => bb.map (b => List (a, b))).flatten
case aa :: bb :: cc =>
xproduct (bb :: cc).map (li => aa.map (a => a :: li)).flatten
case _ => xx
}
Для 2 списков он перенастроен. Вы могли бы назвать его
xproduct (List (l, t))
По-видимому, нет. Я получаю ошибку компиляции, когда я пытаюсь.
Похоже, что.. yield - это выражение. Вы не можете иметь два выхода, так как это не является частью выражения.
Если вы хотите получить несколько значений, почему бы не привести их в виде кортежа или списка?
Например:
for( t <- List(1,2,3); l <- List(-1,-2,-3))
yield (t, l)
Может быть, выход - это не лучший способ? Возможно, здесь может быть использовано простое добавление массива.