Scala: собирать значения, определенные в hashmap, переданном аргументом списка - PullRequest
0 голосов
/ 16 сентября 2018

Предположим, у меня есть следующие переменные:

val m = HashMap( ("1", "one"), ("2", "two"), ("3", "three") )
val l = List("1", "2")

Я хотел бы извлечь список List («один», «два»), который соответствует значениям для каждого ключа в списке, представленном на карте.

Это мое решение, работает как шарм. Тем не менее, я хотел бы знать, изобретаю ли я велосипед заново и есть ли какое-то идиоматическое решение для того, что я собираюсь сделать:

class Mapper[T,V](val map: HashMap[T,V]) extends PartialFunction[T, V]{
    override def isDefinedAt(x: T): Boolean = map.contains(x)

    override def apply(x: T): V = map.get(x) match {
      case Some(v) => v
    }
}

val collected = l collect (new Mapper(map) )

Список («один», «два»)

Ответы [ 3 ]

0 голосов
/ 16 сентября 2018

Я бы предложил что-то вроде этого:

m.collect { case (k, v) if l.contains(k) => v }

Примечание:

  • не сохраняет заказ от l
  • не обрабатывает случай дубликатов в l
0 голосов
/ 16 сентября 2018

Да, вы заново изобретаете колесо. Ваш код эквивалентен

l collect m

, но с дополнительным уровнем косвенности, который ничего не добавляет к HashMap (который уже реализует PartialFunction - просто разверните список "Линейные супертипы", чтобы увидеть это).


В качестве альтернативы вы также можете использовать flatMap следующим образом:

l flatMap m.get

Неявные CanBuildFrom s гарантируют, что результат на самом деле будет List.

0 голосов
/ 16 сентября 2018

Вы можете сделать это, что кажется немного проще:

val res = l.map(m.get(_)) // List(Some("one"), Some("two"))
           .flatMap(_.toList)

Или даже это, используя для понимания:

val res = for {
  key <- l
  value <- m.get(key)
} yield value
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...