Karel Horak
Karel Horak

Reputation: 1062

Extended groupBy

I have a collection of objects, each having a list inside, let us say:

case class Article(text: String, labels: List[String])

I need to construct a map, such that every key corresponds to one of the labels and its associated value is a list of articles having this label.

I hope that following example makes my goal more clear. I want to transform following list

List(
  Article("article1", List("label1", "label2")),
  Article("article2", List("label2", "label3"))
)

into a Map[String,List[Article]]:

Map(
  "label1" -> List(Article("article1", ...)),
  "label2" -> List(Article("article1", ...), Article("article2", ...)),
  "label3" -> List(Article("article2", ...))
)

Is there an elegant way to perform this transformation? (I mean using collection methods without need for using mutable collections directly)

Upvotes: 1

Views: 45

Answers (1)

dhg
dhg

Reputation: 52681

How about this?

val ls = List(
  Article("article1", List("label1", "label2")),
  Article("article2", List("label2", "label3"))
)

val m = ls
    .flatMap{case a @ Article(t,ls) => ls.map(_ -> a)}
    .groupBy(_._1)
    .mapValues(_.map(_._2))

m.foreach(println)
// (label2,List(Article(article1,List(label1, label2)), Article(article2,List(label2, label3))))
// (label1,List(Article(article1,List(label1, label2))))
// (label3,List(Article(article2,List(label2, label3))))

Upvotes: 2

Related Questions