0

I have a map of type:

Map[Int, Seq[Option[User]]]

I want to transform this to:

Map[Int, Seq[User]]

I just want to remove any Option[User] from the Seq.

cool breeze
  • 4,461
  • 5
  • 38
  • 67

2 Answers2

7

Simple Seq#flatten does the magic:

scala> Map(1 -> Seq(Option(1),None, Option(3),None), 2 -> Seq(None))
res1: Map[Int,Seq[Option[Int]]] = 
   Map(1 -> List(Some(1), None, Some(3), None), 2 -> List(None))

scala> res1.mapValues(_.flatten)
res2: Map[Int,Seq[Int]] = Map(1 -> List(1, 3), 2 -> List())
pedrofurla
  • 12,763
  • 1
  • 38
  • 49
  • 2
    Just remember that mapValues works counterintuitvely, by facading the orignal map rather than creating a new one. If this is a problem, you'd need: res1.map {case(k,v) -> k, v.flatten} – Iadams Aug 10 '16 at 15:56
  • what? "Counterintuitively" why? "by facading the orignal map rather than creating a new one" What number 2. So give me an example where this is observable. – pedrofurla Aug 10 '16 at 17:51
  • See http://stackoverflow.com/questions/14882642/scala-why-mapvalues-produces-a-view-and-is-there-any-stable-alternatives – Iadams Aug 10 '16 at 17:53
0
yourMap.map({ case (key, seq) => { 
    (key, seq.filter(uOpt => !uOpt.isEmpty).map(_.get)) 
} })

Or,

val newMap = for {
  (key, seq) <- yourMap
  newSeq = for {
    userOpt <- seq
    if !userOpt.isEmpty
  } yield userOpt.get
} yield (key -> newSeq)
sarveshseri
  • 13,738
  • 28
  • 47