2010-11-18 10 views
16

¿Puedo "ceder" en un mapa?¿Puedo usar for-comprehenion/yield para crear un mapa en Scala?

He intentado

val rndTrans = for (s1 <- 0 to nStates; 
        s2 <- 0 to nStates 
         if rnd.nextDouble() < trans_probability) 
          yield (s1 -> s2); 

(y con , en lugar de ->), pero me sale el error

TestCaseGenerator.scala:42: error: type mismatch; 
found : Seq.Projection[(Int, Int)] 
required: Map[State,State] 
    new LTS(rndTrans, rndLabeling) 

puedo ver por qué, pero no puedo ver cómo resolver este : -/

Respuesta

15
scala> (for(i <- 0 to 10; j <- 0 to 10) yield (i -> j)) toMap 
res1: scala.collection.immutable.Map[Int,Int] = Map((0,10), (5,10), (10,10), (1,10), (6,10), (9,10), (2,10), (7,10), (3,10), (8,10), (4,10)) 
+0

Hmm, probablemente cerca de lo que yo estoy buscando, pero me sale: 'error: valor tomap no es una miembro de Seq.Projection [(Int, Int)] ' – aioobe

+0

Eso es extraño. ¿Qué versión de Scala estás usando? – aioobe

+0

Estoy usando 2.8.0.final –

4

alternativos (obras en 2,7):

scala> Map((for(i <- 0 to 10; j <- 0 to 10) yield (i -> j)): _*) 
res0: scala.collection.immutable.Map[Int,Int] = Map((0,10), (5,10), (10,10), (1,10), (6,10), (9,10), (2,10), (7,10), (3,10), (8,10), (4,10)) 
+0

Genial. Estoy atascado con 2.7 por ahora, así que usaré este. – aioobe

12

Una solución alternativa en Scala 2.8:

Welcome to Scala version 2.8.1.r23457-b20101106033551 (Java HotSpot(TM) Client VM, Java 1.6.0_22). 
Type in expressions to have them evaluated. 
Type :help for more information. 

scala> import scala.collection.breakOut    
import scala.collection.breakOut 

scala> val list: List[(Int,Int)] = (for(i<-0 to 3;j<-0 to 2) yield(i->j))(breakOut) 
list: List[(Int, Int)] = List((0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2), (3,0), (3,1), (3,2)) 

scala> val map: Map[Int,Int] = (for(i<-0 to 3;j<-0 to 2) yield(i->j))(breakOut)  
map: Map[Int,Int] = Map((0,2), (1,2), (2,2), (3,2)) 

scala> val set: Set[(Int,Int)] = (for(i<-0 to 3;j<-0 to 2) yield(i->j))(breakOut) 
set: Set[(Int, Int)] = Set((2,2), (3,2), (0,1), (1,2), (0,0), (2,0), (3,1), (0,2), (1,1), (2,1), (1,0), (3,0)) 

scala> 
+7

+1 para el siempre misterioso (¡pero útil!) BreakOut. Corrígeme si me equivoco, pero creo que ofrece un rendimiento ligeramente mejor porque proporciona un generador que permite la generación directa del mapa (en lugar de construir otra colección que se convierte posteriormente). –

+2

@Zwirb Estás en lo correcto. ¡Y +1 porque no sabía que podrías usarlo con la sintaxis for/yield! :-) –

1
val rndTrans = (
    for { 
    s1 <- 0 to nStates 
    s2 <- 0 to nStates if rnd.nextDouble() < trans_probability 
    } yield s1 -> s2 
) (collection.breakOut[Any, (Int, Int), Map[Int, Int]]) 
Cuestiones relacionadas