2010-11-18 17 views
16

Posso "cedere" a una mappa?Posso usare per comprehenion/yield per creare una mappa in Scala?

Ho provato

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

(e con , invece di ->), ma ottengo l'errore

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

Posso capire perché, ma non riesco a vedere come risolvere questo : -/

risposta

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, probabilmente vicino a quello che sto cercando, ma ottengo: 'errore: valore toMap non è un membro di Seq.Projection [(Int, Int)] ' – aioobe

+0

Questo è strano. Quale versione di Scala stai usando? – aioobe

+0

Sto usando 2.8.0.final –

4

alternativi (opere su 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

Grande. Per ora sono bloccato con 2.7, quindi userò questo. – aioobe

12

Una soluzione alternativa in 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 per il sempre misterioso (ma utile!) Breakout. Correggimi se sbaglio, ma penso che offra prestazioni leggermente migliori perché fornisce un builder che consente la generazione diretta della mappa (invece di costruire un'altra raccolta che viene convertita in seguito). –

+2

@ Zwirb Sei corretto. E +1 perché non sapevo che potevi usarlo con sintassi 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]]) 
Problemi correlati