2013-07-23 1 views
0

Je suis nouveau sur scala, mon objectif est d'itérer sur la liste et de vérifier si les éléments de la liste existent la carte comme ses clés et si elles existent, retourner la valeur pour cette clé.Rechercher des éléments dans une carte

j'ai fait ce qui suit:

def getMatchingValues(listItmes: List[String]) = { 
    for (item <- listItems) { 
     theMap.keys.foreach { i => 
     if (i.equals(item)) { 
      theMap(i) 
     } 
     "NoMatch" 
     } 
    } 
    } 

Je suis en train de comprendre s'il y a une meilleure façon de le faire en scala?

+1

Cette implémentation retournera 'Unit' car vous avez utilisé' foreach'. Quel type de structure de données voulez-vous? –

+0

Peut être une liste, en plus, si j'obtiens une liste, je pourrai aplatir la liste à une chaîne? –

Répondre

4

Carte a une méthode getOrElse qui fait ce que vous voulez:

def getMatchingValues(listItems: List[String]) = listItems map (theMap.getOrElse(_,"NoMatch")) 

Au moins, je pense que c'est ce que vous voulez. Voici un exemple:

scala> val theMap = Map("a"->"A", "b" -> "B") 
theMap: scala.collection.immutable.Map[String,String] = Map(a -> A, b -> B) 

scala> val listItems = List("a","b","c") 
listItems: List[String] = List(a, b, c) 

scala> listItems map (theMap.getOrElse(_,"NoMatch")) 
res0: List[String] = List(A, B, NoMatch) 
+0

C'est génial mais le problème est que je perds la notion de quelle clé avait quel objet. Ou est-ce que je me suis trompé? –

+0

Que voudriez-vous que la sortie soit pour mon exemple avec 'List (" a "," b "," c ")'? 'List ((" a "," A "), (" b "," B "), (" c "," NoMatch "))' peut-être? – stew

2

Une solution possible avec flatMap:

/* Return Some[String] if found, None if not found, then flatten */ 
def getMatchingValues(listItems: List[String], theMap: Map[String, String]): List[String] = 
    listItems.flatMap(item => theMap.get(item)) 

/* Same thing with some syntactic sugar */ 
def getMatchingValuesSmartass(listItems: List[String], theMap: Map[String, String]): List[String] = 
    listItems flatMap theMap.get 

val l = List("1", "3", "5", "7") 
val m = Map("5" -> "five", "2" -> "two", "1" -> "one") 

getMatchingValues(l, m) 
getMatchingValuesSmartass(l, m) 
1

Vous pouvez utiliser la méthode map.get et gérer le résultat avec le modèle correspondant à

list.map { x => map.get(x) match { 
    case None => "No match" 
    case Some(i) => (x, i) 
}} 

Les retours de code ci-dessus une liste de paires où chaque paire représente les éléments de la liste et la valeur associée dans la carte ("Aucune correspondance" si non trouvé)

1

Si j'étais vous, je ferais deux pas. Compte tenu de cette Map:

val map = Map("a" -> "b", "b" -> "c", "c" -> "d", "d" -> "e") 

et ce List:

val list = List("a", "c", "e") 

Au début, je voudrais map une valeur Option à chaque élément de la List. Vous donner s'il y a une valeur pour l'article.

val mapped = list.map(item => item -> map.get(item)) 

Cela vous donnera ceci:

mapped: List[(String, Option[String])] = 
    List(("a",Some("b")), ("c",Some("d")), ("e", None)) 

Appel get sur la carte renvoie un résultat emballé. S'il y a un résultat, vous obtiendrez le résultat enveloppé dans un Some. Sinon, vous obtiendrez un None. Les deux sont des sous-classes de OptionOption est une construction de fermeture, qui vous fournit une valeur nulle sans avoir à traiter null. Maintenant, vous pouvez à nouveau map, pour atteindre votre objectif.

val result = mapped.map(tuple => tuple._1 -> tuple._2.getOrElse("No match")) 
result: List[(String, String)] = List(("a","b"), ("c","d"), ("e","No match")) 

getOrElse extrait la valeur d'un Some ou retombe au paramètre si elle est un None.

Pour le rendre plus professionnel, nous pouvons écrire cette expression dans une ligne;)

val result = list.map(item => item -> map.get(item).getOrElse("No match")) 

Cela vous donnera exactement le même résultat.

Questions connexes