Scala Multimap: получить элемент или пустой набор - PullRequest
4 голосов
/ 05 августа 2011

если я использую мультикарту Scala и хочу получить значения, связанные с ключом или пустым набором, мне нужно написать следующее?

multimap.getOrElse("key", new collection.mutable.HashSet())

Казалось бы, следующее должно работать. Пустой набор выглядит как хорошее значение по умолчанию.

multimap.getOrElse("key")

Ответы [ 4 ]

4 голосов
/ 05 августа 2011

Обычно вы бы использовали Map.withDefaultValue для этого.Тем не менее, похоже, что вы не можете получить такое поведение, и коллекция все еще имеет тип MultiMap[A, B].Тип возврата MultiMap.withDefaultValue - Map[A, Set[B]].Поэтому, к сожалению, вам придется отказаться от использования миксина MultiMap, чтобы получить желаемое поведение.

3 голосов
/ 05 августа 2011

Как вы заметили, черта MultiMap не делает то, что вы хотите.Тем не менее, вы можете добавить значение по умолчанию самостоятельно, если карта является специально изменяемой или неизменной.Вот пример,

scala> val m = collection.mutable.Map(1 -> 2)
m: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)

scala> val m2 = m.withDefaultValue(42)
m2: scala.collection.mutable.Map[Int,Int] = Map(1 -> 2)

scala> m2(1)
res0: Int = 2

scala> m2(2)
res1: Int = 42

Как ни странно, вышеприведенное не сработает, если тип m является абстрактным collection.Map.Комментарий в исходном коде говорит, что это из-за проблем с отклонениями.

0 голосов
/ 03 мая 2016

Поскольку, как отмечено Гарретт Роу , withDefaultValue не сохраняет правильный тип MultiMap при использовании mixin, вы можете вместо этого переопределить метод default в анонимный класс и сохранить поведение MultiMap:

scala> import collection.mutable.{ HashMap, MultiMap, Set }
import collection.mutable.{HashMap, MultiMap, Set}

scala> val map: MultiMap[String, Int] = new HashMap[String, Set[Int]] with MultiMap[String, Int] {
     |   override def default(key: String): Set[Int] = Set.empty[Int]
     | }
map: scala.collection.mutable.MultiMap[String,Int] = Map()

scala> map("foo")
res0: scala.collection.mutable.Set[Int] = Set()

scala> map.addBinding("foo", 1)
res1: map.type = Map(foo -> Set(1))

scala> map("foo")
res2: scala.collection.mutable.Set[Int] = Set(1)
0 голосов
/ 05 августа 2011

withDefaultValue может быть использовано для этого варианта использования. Например:

import collection.mutable._
val multimap = Map[String, HashSet[String]]() withDefaultValue(new HashSet())
scala> multimap("key")
// res1: scala.collection.mutable.HashSet[String] = Set()
...