Suppose I have some class Info
with many attributes, one being categories: Option[List[String]
. I have a list of such Info objects
, eg: val bigList = (Info1,Info2,Info3)
.
I would like to sort bigList
by each category of each element:
sortedList = List((category1,(Info1,Info2,Info3)),(category2,(Info4,Info4)),...)
and so on.
I've tried using groupBy
like such:
val sortedList = bigList.groupBy(_.categories.getOrElse(""))
which doesn't work as certain objects have multiple categories, so it groups objects that share certain categories.
Therefore, is it possible to groupBy each category in the categories attribute?
CodePudding user response:
Sounds like you want to construct a hash map with categories as keys, each entry containing all Info
objects that contain that particular category.
You can achieve this by taking the bigList
and for each element construct a tuple with category as first element. Then you can group by that element and, to make things a bit cleaner, iterate through values in order to remove the categories (we're iterating through hash map values, so we don't need category here, because it's already present in the corresponding hash map key).
Code:
case class Info(categories: Option[List[String]], id: String)
val info1 = Info(Some(List("A")), "1")
val info2 = Info(Some(List("A", "B")), "2")
val info3 = Info(Some(List("B", "C")), "3")
val bigList = List(info1, info2, info3)
def getCategories(info: Info): List[(String, Info)] =
info.categories.getOrElse(List()).map(_-> info)
val result: Map[String, List[Info]] = bigList
.flatMap(getCategories)
.groupBy(_._1)
.view.mapValues(_.map(_._2))
.toMap
// HashMap(
// A -> List(Info(Some(List(A)),1), Info(Some(List(A, B)),2)),
// B -> List(Info(Some(List(A, B)),2), Info(Some(List(B, C)),3)),
// C -> List(Info(Some(List(B, C)),3))
// )