Лучший способ «изменить» неизменную карту - обратиться к ней в переменной (var
вместо val
):
var tree = TreeMap.empty[String, List[String]]
tree += ("k1" -> List("foo", "bar")) //a += b is sugar for "c = a + b; a = c"
быть доступным напрямую, используя метод apply
, где включается синтаксический сахар scala, так что вы можете просто получить доступ, используя parens:
val l = tree("k1") //equivalent to tree.apply("k1")
Однако я редко обращаюсь к таким картам, потому что метод выдает MatchError
это ключа нету.Вместо этого используйте get
, который возвращает Option[V]
, где V
- это тип значения:
val l = tree.get("k1") //returns Option[List[String]] = Some(List("foo", "bar"))
val m = tree.get("k2") //returns Option[List[String]] = None
В этом случае значение, возвращаемое для отсутствующего ключа, равно None
.Что я могу сделать с необязательным результатом?Ну, вы можете использовать методы map
, flatMap
, filter
, collect
и getOrElse
.Попробуйте избежать сопоставления с образцом или используйте метод Option.get
напрямую!
Например:
val wordLen : List[Int] = tree.get("k1").map(l => l.map(_.length)) getOrElse Nil
РЕДАКТИРОВАТЬ : Один из способов построения карты, не объявляя ее var
, и предполагая, что вы делаете это путем преобразования какой-то отдельной коллекции, состоит в том, чтобы сделать это через сгиб.Например:
//coll is some collection class CC[A]
//f : A => (K, V)
val m = (TreeMap.empty[K, V] /: coll) { (tree, c) => tree + f(c) }
Это может быть невозможно для вашего варианта использования