I would like to group a sequence into a sequence map based on an discriminator of type Option , similar to the result of the groupBy method, but where the values ββleading to None are discarded. Or perhaps grouping with the PartialFunction discriminator and dropping those for which an incomplete function is not defined.
Here is a concrete example:
I have a collection of namespaces and a collection of namespaces. Some, but not all, names belong to a valid namespace, and I want to group those that do in Map, discarding those that don't.
Currently my solution is equivalent to:
val names = List("ns1.foo", "ns2.bar", "ns2.baz", "froznit") val namespaces = List("ns1", "ns2") def findNamespace(n: String): Option[String] = namespaces.find(n.startsWith) val groupedNames = names.groupBy(findNamespace).collect { case (Some(ns), name) => (ns, name) }
My concern with this solution is that using names.groupBy(findNamespace) , I create an intermediate map that contains all the names that I donβt need, under the None key. If the number of names that I drop becomes large, this decision becomes less attractive.
My attempt to avoid this is a little about behavior, but:
val groupedNames = names. map(n => (findNamespace(n), n)). collect({ case (Some(ns), n) => (ns, n) }). groupBy(_._1). map({ case (ns, names) => (ns, names.map(_._2)) })
If you decided it wiser, what would it be?
Edit: ideally, the solution should only call findNamespace(name) once for each name and build the map using only the Option[String] values, without calling a separate hasNamespace(name) predicate.