2010-09-30 9 views
3

Comment puis-je utiliser une for-comprehension qui renvoie quelque chose que je peux assigner à une carte ordonnée? Ceci est une simplification du code je:Scala pour la compréhension renvoyant une carte ordonnée

class Bar 
class Foo(val name: String, val bar: Bar) 
val myList: java.util.List[Foo] = ... 
val result: ListMap[String, Bar] = 
    for { 
     foo <- myList 
    } yield (foo.name, foo.bar) 

je dois vous assurer que mon résultat est une carte ordonnée, dans les tuples de commande sont renvoyés par la pour compréhension orale.

Avec ce qui précède, je reçois l'erreur:

error: type mismatch; 
found : scala.collection.mutable.Buffer[(String,Bar)] 
required: scala.collection.immutable.ListMap[String,Bar] 
foo <- myList 

Cette compile:

class Bar 
class Foo(val name: String, val bar: Bar) 
val myList: java.util.List[Foo] = ... 
val result: Predef.Map[String, Bar] = 
    { 
     for { 
      foo <- myList 
     } yield (foo.name, foo.bar) 
    } toMap 

mais je suppose la carte ne sera pas commandé, et je besoin d'un appel toMap explicite.

Comment puis-je y parvenir?

Répondre

4

Vous pouvez obtenir le faire en utilisant l'objet compagnon de classe ListeCarte comme suivants:

class Bar 
class Foo(val name: String, val bar: Bar) 
val myList: java.util.List[Foo] = ... 
val result = ListMap((for(foo <- myList) yield (foo.name, foo.bar)):_*) 
+0

Pourriez-vous expliquer ce que signifie l'ajout: \ _ \ *? – xiaohan2012

+0

Dans le cas où vous ne l'avez jamais compris; C'est juste une syntaxe spéciale pour dire "insérer ce truc dans une méthode qui prend vargs", c'est-à-dire 'public void foo (String ...)' – habitats

7

Le collection.breakOut est votre bon ami dans un tel cas,

val result: collection.immutable.ListMap[String, Bar] = 
    myList.map{ foo => (foo.name, foo.bar) }(collection.breakOut) 

S'il est important d'utiliser pour la compréhension-expression, il se fera comme suit,

val result: collection.immutable.ListMap[String, Bar] = { 
    for { foo <- myList } yield (foo.name, foo.bar) 
}.map(identity)(collection.breakOut) 

Scala 2.8 breakOut a expliqué collection.breakOut très bien.

+0

J'ai essayé avec et sans .map (identité) et les deux semblent compiler correctement. Y a-t-il une différence entre utiliser .map (identité) ou non? – ebruchez

+0

Dans le premier cas, ListMap sera généré directement à partir de myList, mais ce dernier générera un seq à partir de myList, puis générera ListMap à partir de celui-ci. – ymnk