Как найти карту в списке карт, где ключ имеет определенное значение в Scala? - PullRequest
0 голосов
/ 31 января 2019

У меня есть List[Map[String, Any], и я хочу вернуть карту, которая имеет определенное значение для одного из ключей.Вот такой пример:

val items: List[Map[String, Any]] = List(Map("name" -> "A", "size" -> 50), Map("name" -> "B", "size" -> 75), Map("name" -> "C", "size" -> 100)))

val mapB: Map[String, Any] = items.find(|m| m("name") == "B") // Psuedo code

mapB будет Map("name" -> "B", "size" -> 75).

Бонусный вопрос

Есть ли способ возвратазначение другого ключа вместо целого Map?

Например, если бы я хотел только значение size (75) для name B?Я знаю, что могу извлечь его из Map как двухэтапную операцию, но если есть другой, более идиоматический способ, мне было бы интересно изучить его.

Спасибо!

Ответы [ 2 ]

0 голосов
/ 31 января 2019

Дополнение ответов jwvh (и использование предложения Тима для повышения безопасности) .
Вот функция, которая отвечает на ваш бонусный вопрос.

def findAndGet(maps: List[Map[String, Any]], condition: (String, Any), key: String): Option[Any] = condition match {
  case (k, v) =>
    maps.find(map => map.get(k).contains(v)).flatMap(map => map.get(key))
}
findAndGet(maps = items, condition = ("name", "B"), key = "size")
// res0: Option[Any] = Some(75)

Кстати,Map[String, Any] дает мне понять, что вы имеете дело с JSONs , вы обратились к какой-либо из библиотек Scala, чтобы справиться с ними "более безопасным" способом?, Имея в своем коде Anyвсегда должна быть тревога, что что-то не так .

0 голосов
/ 31 января 2019

find() возвращает Option в случае, если то, что вы ищете, не может быть найдено.

val mapB: Option[Map[String, Any]] = items.find(_("name") == "B") //safe

или

val mapB: Map[String, Any] = items.find(_("name") == "B").get //unsafe, might throw

Для извлечения size значение из первого Map, где "name" -> "B" вы можете сделать что-то вроде этого.

val sz :Any = items.find(m => m.get("name").contains("B")
                           && m.get("size").nonEmpty).fold(0:Any)(_("size"))

Обратите внимание, что sz имеет тип Any, потому что это тип значений Map.Это означает, что вам придется разыграть его (обескуражить), набрав Int, прежде чем вы сможете сделать что-нибудь полезное с ним.

Избегайте ввода Any.Это верный признак того, что вы идете в неправильном направлении.

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