2010-06-01 19 views
20

Cuando evalúo un for en Scala, me sale un inmutable IndexedSeq (una colección con las características de la matriz como de rendimiento, tales como acceso aleatorio eficiente):tipo Colección generada por para con el rendimiento

scala> val s = for (i <- 0 to 9) yield math.random + i 
s: scala.collection.immutable.IndexedSeq[Double] = Vector(0.6127056766832756, 1.7137598183155291, ... 

¿Un for con un yield siempre devuelve un IndexedSeq, o también puede devolver algún otro tipo de clase de colección (un LinearSeq, por ejemplo)? Si también puede devolver algo más, ¿qué determina el tipo de devolución y cómo puedo influir en él?

Estoy usando Scala 2.8.0.RC3.

+3

Tenga una mirada en http://stackoverflow.com/questions/1052476/can-someone-explain-scalas-yield/1059501 # 1059501 y http://stackoverflow.com/questions/1721356/scala-2-8-canbuildfrom –

Respuesta

18

Gracias michael.kebe por su comentario.

This explica cómo for se traduce a las operaciones con map, flatMap, filter y foreach. Así que mi ejemplo:

val s = for (i <- 0 to 9) yield math.random + i 

se traduce a algo como esto (no estoy seguro de si se traduce a map o flatMap en este caso):

val s = (0 to 9) map { math.random + _ } 

El tipo de resultado de operaciones como map en colecciones depende de la colección que lo llame. El tipo de 0 to 9 es un Range.Inclusive:

scala> val d = 0 to 9 
d: scala.collection.immutable.Range.Inclusive with scala.collection.immutable.Range.ByOne = Range(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) 

El resultado de la operación map en que es una IndexedSeq (debido a la materia constructor dentro de la biblioteca colecciones).

Por lo tanto, para responder a mi pregunta: el resultado de for (...) yield ... depende del tipo que se encuentre dentro de las parantheses. Si quiero un List como resultado, que podría hacer esto:

scala> val s = for (i <- List.range(0, 9)) yield math.random + i 
s: List[Double] = List(0.05778968639862214, 1.6758775042995566, ... 
+2

Se tradujo al mapa en su caso. Si tiene una para la comprensión con dos generadores, esto se traduce en una combinación flatMap/map. Entonces para (i <- 0 hasta 9; j <- 0 hasta i) el rendimiento (i * j) se traduce a (0 hasta 9) .flatMap {caso i => (0 hasta i) .map {caso j => i * j}} –

+0

"depende del tipo que está dentro de la parantheses", más preciso es el primer parámetro del lado derecho que determina el tipo. –

5

siempre se puede transformar un rango a una lista utilizando toList:

> val s = for (i <- (0 to 9).toList) yield math.random + i 
> s : List[Double] 
Cuestiones relacionadas