Home > database >  Scala GroupBy elements inside a nested List
Scala GroupBy elements inside a nested List

Time:10-19

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))
//  )
  • Related