Cómo usar un valor de mapa en una declaración de caso de coincidencia en Scala

Tengo un mapa como este:

val mealIdsMap: Map[String, String]    =
Map (
      "breakfast"     ->    "omelet",
      "lunch"         ->    "steak",
      "dinner"        ->    "salad"
)

Luego trato de usarlo en una declaración de coincidencia como esta:

"omelet" match 
{ 
  case mealIdsMap("breakfast") => "Thank God"
}

Y me sale este error:

error: value mealIdsMap is not a case class constructor,
nor does it have an unapply/unapplySeq method
              case mealIdsMap("breakfast") => "Thank God"

¿Alguien sabe cómo usar un mapa como este en una declaración de coincidencia/caso?

Muchas gracias por tu ayuda.

preguntado el 03 de mayo de 12 a las 15:05

2 Respuestas

Debería leer cuál es el propósito de la coincidencia de patrones de un tutorial, puede ser de esta (primer ejemplo no trivial en google).

Has invertido la prueba:

mealIdsMap("breakfast") match {
  case "omelet" => "Thank God"
  case _ => "Don't forget a default"
}

Y si no está seguro de que la clave esté presente (e incluso si lo está, si desea escribir scala idiomática, debería preferir:

mealIdsMap.get("breakfast") match {
  case Some("omelet") => "Thank God"
  case _ => "Don't forget a default"
}

Dónde getdevuelve una opción, evitando que intente capturar su código o dejar que se rompa en silencio.

contestado el 03 de mayo de 12 a las 15:05

Muchas gracias Nicolás. Eso ayudó. - davidson

Sin embargo, sigue siendo interesante tratar de lograr tal comportamiento. echa un vistazo a este ejemplo:

  case class InvMatcher (m:Map[String, String]){
 def unapply(v:String):Option[String] = {
   return m collectFirst {case (k, `v`) => k}
 }

}

Esta clase te ayuda a hacer coincidir inversamente un mapa. uso:

val ma = InvMatcher (Map (
  "breakfast"     ->    "omelet",
  "lunch"         ->    "steak",
  "dinner"        ->    "salad"
));

"steak" match {
  case ma(s) => s match {
    case "breakfast" => print("Thank God")
    case "lunch" => print("whatever")

    case _ => print("dont forget default")
  }
  case _ => print("dont forget default")
}

Esto es casi como lo quería, aunque necesita una segunda declaración de coincidencia (que no necesita un caso predeterminado aquí...)

contestado el 07 de mayo de 12 a las 13:05

Puede ser un poco pronto para introducir la magia de no aplicar para los pactos y estoy bastante seguro de que se puede realizar una mejor implementación. - Nicolas

Lo analicé más a fondo: puede reemplazar su código no aplicado con: m collectFirst {case (k, `v`) => k} - Nicolas

cambié el ejemplo, aunque todavía necesito un protector, ya que no quiero probar 'v' pero el valor de v - wrm

Este es exactamente el propósito de las comillas inversas (`v`). además, en la segunda parte, necesita 2 casos predeterminados (uno para cada match). - Nicolas

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.