У меня есть Map[A, Option[B]]
, что является оптимальным способом сделать сглаживание, чтобы получить Map[A, B]
?Спрятать карту опциона для карты
Я знаю, что для списка, мы можем использовать выравниваться, но эта структура отличается
У меня есть Map[A, Option[B]]
, что является оптимальным способом сделать сглаживание, чтобы получить Map[A, B]
?Спрятать карту опциона для карты
Я знаю, что для списка, мы можем использовать выравниваться, но эта структура отличается
Ну, они не то же самое, так что вам нужен способ, чтобы определить, что произойдет, если значение Нет. Я предполагаю, что вы хотите игнорировать эти ключи, если да, то вы можете получить с помощью частичной функции:
map.collect {
case (k, Some(v)) => k -> v
}
или использовать для понимания-
for ((k, Some(v)) <- map) yield k -> v
Если вы не возражаете двойной итерации:
map.filter(_._2.nonEmpty).mapValues(_.get)
Пример:
scala> Map(1 -> Some(1), 2 -> None).filter(_._2.nonEmpty).mapValues(_.get)
res9: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
Или используя этот неявный:
implicit def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList
Тогда:
map.flatten.toMap
Или без использования (потенциально небезопасно) неявный:
map flatMap flat
Пример:
scala> Map(1 -> Some(1), 2 -> None).flatten.toMap
res2: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
scala> def flat[K,V](kv: (K, Option[V])) = kv._2.map(kv._1 -> _).toList
warning: there was one feature warning; re-run with -feature for details
flat: [K, V](kv: (K, Option[V]))List[(K, V)]
scala> Map(1 -> Option(1), 2 -> None).flatMap(flat)
res29: scala.collection.immutable.Map[Int,Int] = Map(1 -> 1)
Стоит отметить, что 'mapValues' возвращает вид на карту, что, вероятно, не соответствует требованиям OP. – jhn
@jhn зависит, если код внутри mapValues является ссылочным-прозрачным, как в моем ответе, зачем кому-то это нужно? Для Java-сериализации (если по-прежнему ее используют по какой-либо причине) всегда есть .view.force или .map (identity) – dk14
Зачем кому-то это нужно? Представление. – jhn
да Я не уточнил, что я не хочу ключа с None, спасибо за ваш ответ! – nam
Фактически 'for ((k, Some (v)) <- map) yield k -> v' достаточно – dk14
очень верно! Я обновлю! Этот шаблон совпадал выше, а не ниже, идиот ... –