Карта только с определенными ключами - PullRequest
6 голосов
/ 15 февраля 2012

Что касается карт в Scala, если ms - (k, 1, m) возвращает карту, содержащую все сопоставления с ms , за исключением для любого сопоставления с заданными ключами, x, 1 и m.

Тогда, какой оператор вернет карту всех отображений ms с только данными ключами, x, 1 и m. то есть я ищу подмножество ms, где только k, 1 и m являются ключами.

Это работает, но ужасно:

scala> val originalMap = Map("age" -> "20", "name" -> "jack", "hobby" -> "jumping")
ms: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20, name -> jack, hobby -> jumping)

scala> val interestingKeys = List("name", "hobby")
interesting: List[java.lang.String] = List(name, hobby)

scala> val notInterestingMap = originalMap -- interestingKeys
notInterestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(age -> 20)

scala> val interestingMap = originalMap -- notInterestingMap.keySet
interestingMap: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping)

Ответы [ 3 ]

7 голосов
/ 15 февраля 2012

Поскольку filterKeys фильтрует на основе произвольного предиката, он должен учитывать каждый ключ на карте.Это может быть хорошо или нет, в зависимости от размера карты и т. Д., Но это определенно не обязательно для описываемой вами операции.Я бы использовал что-то вроде следующего:

interestingKeys.flatMap(k => originalMap.get(k).map((k, _))).toMap

Это будет O(n) или O(n log m) в зависимости от реализации вашей карты (где n - это размер interestingKeys, а m - эторазмер карты) вместо O(m log n) или O(mn).

Если вы действительно хотите использовать оператор ~, вы можете использовать шаблон pimp-my-library :

class RichMap[A, B](m: Map[A, B]) {
  def ~(ks: A*) = ks.flatMap(k => m.get(k).map((k, _))).toMap
}

implicit def enrichMap[A, B](m: Map[A, B]) = new RichMap(m)

Теперь originalMap ~ ("name", "hobby") возвращает Map(name -> jack, hobby -> jumping), как и следовало ожидать.

7 голосов
/ 15 февраля 2012

filterKeys может помочь:

scala> originalMap.filterKeys(interestingKeys.contains)
res0: scala.collection.immutable.Map[java.lang.String,java.lang.String] = Map(name -> jack, hobby -> jumping)
2 голосов
/ 03 октября 2017

Я думаю, что оригинальный код не так уж и плох, и его можно легко преобразовать в однострочник, работающий с наборами ключей:

val interestingMap = originalMap -- (originalMap.keySet -- interestingKeys)

Я нахожу это вполне читабельным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...