sociales redes mediatica informacion scala scala-collections

scala - redes - informacion mediatica



Cómo implementar Map con la operación predeterminada en Scala (5)

¿Por qué no usar withDefaultValue (value)?

scala> val m = Map[Int, List[String]]().withDefaultValue(List()) m: scala.collection.immutable.Map[Int,List[String]] = Map() scala> m(123) res1: List[String] = List()

class DefaultListMap[A, B <: List[B]] extends HashMap[A, B] { override def default(key: A) = List[B]() }

Quiero crear el mapa A -> List[B] . En mi caso, es Long -> List[String] pero cuando obtengo una clave del mapa que no tiene valor, me gustaría crear una List vacía en lugar de una Exception . Probé diferentes combinaciones, pero no sé cómo hacer que el código pase el compilador.

Gracias por adelantado.


¿Por qué quieres manipular un mapa cuando ya tiene un método para esto?

val m = Map(1L->List("a","b"), 3L->List("x","y","z")) println(m.getOrElse(1L, List("c"))) //--> List(a, b) println(m.getOrElse(2L, List("y"))) //--> List(y)


En lugar de utilizar apply para acceder al mapa, siempre get usar get , que devuelve la Option[V] y luego getOrElse :

map.get(k) getOrElse Nil

Una gran característica de la biblioteca de programación funcional de Scalaz es el operador unario ~ , que significa "o cero", siempre que el tipo de valor tenga un "cero" definido (qué List hace, siendo el cero Nil por supuesto). Entonces el código se convierte en:

~map.get(k)

Esto es doblemente útil porque la misma sintaxis funciona donde (por ejemplo) sus valores son Int , Double , etc. (cualquier cosa para la que haya una clase de tipo Zero ).

Ha habido un gran debate en la lista de correo de Map.withDefault sobre el uso de Map.withDefault debido a cómo se comporta con el método isDefinedAt , entre otros. Por esta razón, tiendo a evitarlo.


Hay un método con withDefaultValue en Map :

scala> val myMap = Map(1 -> List(10), 2 -> List(20, 200)).withDefaultValue(Nil) myMap: scala.collection.immutable.Map[Int,List[Int]] = Map((1,List(10)), (2,List(20, 200))) scala> myMap(2) res0: List[Int] = List(20, 200) scala> myMap(3) res1: List[Int] = List()


withDefault también se puede usar.

/** The same map with a given default function. * Note: `get`, `contains`, `iterator`, `keys`, etc are not affected * by `withDefault`. * * Invoking transformer methods (e.g. `map`) will not preserve the default value. * * @param d the function mapping keys to values, used for non-present keys * @return a wrapper of the map with a default value */ def withDefault[B1 >: B](d: A => B1): immutable.Map[A, B1]

Ejemplo:

scala> def intToString(i: Int) = s"Integer $i" intToString: (i: Int)String scala> val x = Map[Int, String]().withDefault(intToString) x: scala.collection.immutable.Map[Int,String] = Map() scala> x(1) res5: String = Integer 1 scala> x(2) res6: String = Integer 2

Espero que esto ayude.