I have a list:
List[Any]("foo", 1, 2, "bar", 3, 4, 5)
I would like to group it's elements this way:
Map("foo" -> List(1,2), "bar" -> List(3,4,5))
I can only imagine a solution in an imperative style with mutable lists and vars, but what is the proper way of solving this task?
Straightforward.
If the list has elements, take all ints from the tail and drop the rest, which is stored in rest. That is what span does. Then map the head to the ints and recursivly do it for the rest.
def f(a: List[Any]): Map[String, List[Int]] = a match {
case Nil => Map.empty
case head :: tail => {
val (ints, rest) = tail.span(_.isInstanceOf[Int])
f(rest) + (head.asInstanceOf[String] -> ints.map(_.asInstanceOf[Int]))
}
}
Consider multiSpan as defined in https://stackoverflow.com/a/21803339/3189923 ; then for
val a = List[Any]("foo", 1, 2, "bar", 3, 4, 5)
we have that
val b = a.multiSpan(_.isInstanceOf[String])
b: List[List[Any]] = List(List(foo, 1, 2), List(bar, 3, 4, 5))
and so
b.map { l => (l.head, l.tail) }.toMap
res: Map(foo -> List(1, 2), bar -> List(3, 4, 5))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With