Подтвердить что ты не робот

Фильтровать карту для значений None

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

val map = Map[String, Option[Int]]("one" -> Some(1), 
                                   "two" -> Some(2), 
                                   "three" -> None)

Я бы хотел вернуть карту с помощью пары ("one", Some(1)) и ("two", Some(2)). Я понимаю, что это делается при сглаживании, когда у вас есть список, но я не уверен, как добиться эффекта на карте, не разбивая ее на ключи и значения, а затем пытаться воссоединиться с ними.

4b9b3361

Ответ 1

Как и каждый тип коллекции в пространстве имен scala.collection, Map имеет метод filter, а Option имеет метод isDefined, который true для Some и false для None. Вы можете отфильтровать значения None, объединив эти два параметра:

scala> map.filter(_._2.isDefined)
res4: scala.collection.immutable.Map[String,Option[Int]] = Map(one -> Some(1), two -> Some(2))

Ответ 2

Если вы отфильтровываете значения None, вы можете также извлечь значения Some в одно и то же время, в результате получив Map[String,Int]:

scala> map.collect { case (key, Some(value)) => (key, value) }
res0: scala.collection.immutable.Map[String,Int] = Map(one -> 1, two -> 2)

Ответ 3

Также map.filterKeys( map(_) != None)

или

for( (k,v) <- map if( v!= None)) yield (k,v)

Этот подход обеспечивает общий метод filterValues, который не существует на картах.
Я пропустил такой метод, потому что ни одна из альтернатив не идеальна.

[Обновлено позже] Это более эффективная версия, которая не выполняет поиск по каждой записи и все еще читается достаточно четко.

map.filter( {case (x,y)=> y!=None})