2009-07-16 17 views

Respuesta

21

No está claro lo que está pidiendo, lo que espera que sea la semántica del rendimiento múltiple. Una cosa, sin embargo, es que probablemente nunca desee utilizar índices para navegar por una lista: cada llamada a t (i) es O (i) para ejecutar.

Así que aquí es una posibilidad 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 tarde es el azúcar solo 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 quiera intercalarlos

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) 

Ese es el azúcar sintaxis para

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

Creo que solo quiere interpolar las listas. –

+0

a la derecha, quería intercalarlos, por lo que ambos dan el mismo resultado: [James] val intercalado = para ((x, y) <- l zip t; r <- Lista (x, y)) rendimiento r [Daniel] para (i <- 0 a 10; r <- Lista (l (i), t (i))) rendimiento r Creo que una James' es más elegante y que da salida también Lista . Muchas gracias chicos. –

0

Aparentemente no. Obtengo un error de compilación cuando lo intento.

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

Si desea obtener múltiples 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) 
0

Tal rendimiento no es el mejor camino a seguir? Tal vez el arsenal de anexos simple podría usarse aquí.

+0

No hay diferencia semántica entre usar rendimiento y usar una lista. La diferencia práctica implica el uso de memoria, donde el rendimiento es más eficiente para conjuntos grandes. – Christopher

5

No, no puede usar varias cláusulas de rendimiento, pero hay soluciones alternativas. 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 es lo que desea.

+1

Advertencia, esta solución es O (n^2) –

+0

Para l & t listas, que fue, voy a conceder, su ejemplo. Si t & l fueran matrices o funciones, ese no sería el caso, ¿verdad? –

+0

Derecha, para el acceso indexado de matrices es O (1) por lo que la solución sería O (n). –

1

Aquí es una solución de tipo agnóstica 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 se es sobrediseñado Aunque podría llamarlo

xproduct (List (l, t)) 
2

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

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 aplanado es semánticamente diferente.

Cuestiones relacionadas