Convert list [Task (username, description)] to Map [username, Set [Task]]

(NOTE: I stop working with Scala and continue to struggle with the most common collection manipulation operations.)

I would like to convert a List [Task] to a Map. Here are some details:

// assignee may be null
case class Task(assignee: String, description: String)
// might refactor it into:
// case class Task(assignee: Option[String], description: String)

      

I want a Map where Keys are assignees and each value is a Set [Task]. I am having trouble managing the following two situations:

  • The map is not (cough) friendly (cough) with null keys (I worked on this with the [String] option for assignee) and
  • need to distinguish if the key exists in the map (just add the value to the existing set) and the key has already been added, so the Set value exists

I came up with the following, but it looks too verbose.

def groupByAssignee(tasks : List[Task]) : Map[Option[String], Set[Task]] = {
 tasks.foldLeft(Map[Option[String], Set[Task]]())(
  (m, t) => {
    m.get(t.assignee) match {
      case Some(_) => m + ((t.assignee, m.get(t.assignee).get.+(t)))
      case _       => m + ((t.assignee, Set(t)))
    }
  })
}

      

What's an easier / cleaner way to achieve this?

Thank!

+3


source to share


1 answer


This use case is so common that there is a built-in method for it:

tasks groupBy {_.assignee}

      

groupBy

however will return Map[String,List[Task]]

as long as you want .Map[String, Set[String]]

. This should do it:



groupBy {_.assignee} mapValues {_ map {_.description} toSet}

      

groupBy

null

- friendly, but you don't have to be. Option[String]

much better and more idiomatic.

+5


source







All Articles