Filter map for values of None

40,989

Solution 1

Like every collection type in the scala.collection namespace a Map has the filter method defined and Optionhas the isDefined method, which is true for Some and false for None. You can filter out the Nonevalues by combining these two:

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

Solution 2

If you're filtering out None values, you might as well extract the Some values at the same time to end up with a Map[String,Int]:

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

Solution 3

Also map.filterKeys( map(_) != None)

or

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

This approach provides a general filterValues method that doesn't exist on maps.
I miss such a method, because none of the alternatives is perfect.

[Updated later] This is a better version that doesn't do a lookup on each entry and still reads reasonably clearly.

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

Share:
40,989
KChaloux
Author by

KChaloux

Updated on August 17, 2020

Comments

  • KChaloux
    KChaloux over 3 years

    I've searched around a bit, but haven't found a good answer yet on how to filter out any entries into a map that have a value of None. Say I have a map like this:

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

    I'd like to end up returning a map with just the ("one", Some(1)) and ("two", Some(2)) pair. I understand that this is done with flatten when you have a list, but I'm not sure how to achieve the effect on a map without splitting it up into keys and values, and then trying to rejoin them.

  • KChaloux
    KChaloux over 11 years
    Neato. I wouldn't have guessed the syntax though. Still a little confused on _. From what I understand, we're telling it to go to the second item (the value) of the first (current) pair?
  • Nikita Volkov
    Nikita Volkov over 11 years
    @KChaloux In this case _ refers to the first argument of a function literal being passed to the filter method. It's a shorthand for x => x._2.isDefined
  • fracz
    fracz over 8 years
    And the _2 comes from the Tuple.