Search code examples
scalafunctional-programmingtuplesmultimap

Filtering a Scala Multimap and outputting as a list of Tuples


I have a map using the multimap trait, like so
val multiMap = new HashMap[Foo, Set[Bar]] with MultiMap[Foo, Bar]
I would like to combine filtering this map on specific values
multiMap.values.filter(bar => barCondition)
with flattening the matching results into a list of tuples of the form
val fooBarPairs: List[(Foo, Bar)]
What would be the idiomatic way of doing this? I was hoping that Scala might provide something like an anamorphism to do this without looping, but as a complete newbie I am not sure what my options are.


Solution

  • Here's an example:

    import collection.mutable.{HashMap, MultiMap, Set}
    
    val mm = new HashMap[String, Set[Int]] with MultiMap[String, Int]
    mm.addBinding("One", 1).addBinding("One",11).addBinding("Two",22).
      addBinding("Two",222)
      // mm.type = Map(Two -> Set(22, 222), One -> Set(1, 11))
    

    I think the easiest way to get what you want is to use a for-expression:

    for {
      (str, xs) <- mm.toSeq
      x         <- xs
      if x > 10
    } yield (str, x)      // = ArrayBuffer((Two,222), (Two,22), (One,11))
    

    You need the .toSeq or the output type will be a Map, which would mean each mapping is overidden by subsequent elements. Use toList on this output if you need a List specifically.