Pregunta

Un ejemplo:

val l = List(1,2,3)
val t = List(-1,-2,-3)

¿Puedo hacer algo como esto?

for (i <- 0 to 10) yield (l(i)) yield (t(i))

Básicamente quiero dar varios resultados para cada iteración.

¿Fue útil?

Solución

No está claro lo que está pidiendo - lo que espera la semántica de rendimiento múltiple que se desea. Una cosa, sin embargo, es que probablemente nunca quiere utilizar índices para navegar por una lista -. Cada llamada a T (i) es O (i) para ejecutar

Así que aquí hay una posibilidad de que se puede preguntar por

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

Y aquí hay otra posibilidad que se puede preguntar por

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

La última es simplemente azúcar sintáctica para

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

Una tercera posibilidad es que desea intercalar ellos

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)

Eso es azúcar sintaxis de

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)

Otros consejos

No, no se puede utilizar varias cláusulas de rendimiento, pero hay soluciones temporales. Por ejemplo:

for (i <- 0 to 10;
     r <- List(l(i), t(i)))
yield r

Puede anidar para-comprensiones, por supuesto, pero eso daría lugar a una lista de listas de elementos, que no creo que es lo que desea.

Los rendimientos se pueden anidar, lo que daría lugar ...

for (i <- 0 to 3) yield {
  for (j <- 0 to 2) yield (i,j)
}

en un vector de 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)

La solución aplanada es semánticamente diferente.

Aquí es una solución de tipo agnóstico para un número variable desconocida, de elementos en un número desconocido de listas:

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
}

Para 2 Listas es overengineered. Aunque se podía llamarlo

   xproduct (List (l, t))

Al parecer no. Me sale un error de compilación cuando lo intento.

Parece que para .. rendimiento es una expresión. No se puede tener dos rendimientos, ya que eso no es realmente parte de la expresión.

Si desea obtener varios valores, por qué no cederlos como una tupla o una lista?

Por ejemplo:

for( t <- List(1,2,3); l <- List(-1,-2,-3))
  yield (t, l)

Tal vez rendimiento no es el mejor camino a seguir? Tal vez sencilla anexar matriz podría ser utilizado aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top