(NOTE I’m quit new to Scala and still struggle with most common operations of collection manipulation.)
I would like to convert a List[Task] into a Map. Here’s 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 the assignees and each Value is a Set[Task]. I’m having trouble managing the following two situations:
- Map’s not being (cough) friendly (cough) with null Keys (I worked around this one using Option[String] for assignee) and
- having to distinguish whether a Key already exists in the map (only add value to existing set) vs key already added so the Set value exists
I came up with the following but it looks overly 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 a easier/clearer way to achieve this?
Thanks!
This use case is so common that there is a built-in method for that:
groupByhowever will returnMap[String,List[Task]]while you want.Map[String, Set[String]]. This should do it:groupBYisnull-friendly, but you shouldn’t be.Option[String]is much better and more idiomatic.