2010-06-01 5 views
20

Lorsque j'évalue un for à Scala, je reçois un IndexedSeq immuable (une collection avec des caractéristiques de performance semblable à un tableau, comme l'accès aléatoire efficace):Type de collection généré par pour avec un rendement

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

Est-ce un for avec yield retourne toujours un IndexedSeq, ou peut-il aussi retourner un autre type de classe de collection (un LinearSeq, par exemple)? S'il peut aussi retourner quelque chose d'autre, qu'est-ce qui détermine le type de retour, et comment puis-je l'influencer? J'utilise Scala 2.8.0.RC3.

+3

Jetez un oeil à http://stackoverflow.com/questions/1052476/can-quelqu'un-expliquer-scalas-rendement/1059501 # 1059501 et http://stackoverflow.com/questions/1721356/scala-2-8-canbuildfrom –

Répondre

18

Merci michael.kebe pour votre commentaire.

This explique comment for se traduit à des opérations avec map, flatMap, filter et foreach. Donc, mon exemple:

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

est traduit à quelque chose comme ça (je ne sais pas si elle est traduite map ou flatMap dans ce cas):

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

Le type de résultat des opérations telles que map sur collections dépend de la collection sur laquelle vous l'appelez. Le type de 0 to 9 est 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) 

Le résultat de l'opération map sur c'est un IndexedSeq (à cause de la substance de constructeur dans la bibliothèque de collections). Donc, pour répondre à ma question: le résultat d'un for (...) yield ... dépend du type qui est à l'intérieur des parenthèses. Si je veux un List que le résultat, je pouvais le faire:

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

Il est traduit à la carte dans votre cas. Si vous avez un pour la compréhension avec deux générateurs, cela se traduit par une combinaison flatmap/carte. Donc pour (i <- 0 jusqu'à 9; j <- 0 jusqu'à i) le rendement (i * j) est traduit en (0 jusqu'à 9) .flatMap {case i => (0 jusqu'à i) .map {case j => i * j}} –

+0

"dépend du type qui est à l'intérieur des parenthèses", plus précis c'est le premier paramètre du côté droit qui détermine le type. –

5

Vous pouvez toujours transformer une plage à une liste à l'aide toList:

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