将列表[任务(用户名,描述)]转换为Map [用户名,设置[任务]]

ign*_*i35 3 collections grouping scala

(注意我已经放弃了Scala的新功能,并且仍然在处理集合操作的大多数常见操作.)

我想将List [Task]转换为Map.这是一些细节:

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

我想要一个Map,其中Keys是受让人,每个Value都是Set [Task].我无法管理以下两种情况:

  • 地图不是(咳嗽)友好(咳嗽)与键(我使用选项[字符串]为受让人工作)和
  • 必须区分地图中是否已存在密钥(仅添加现有集合的值)与已添加的密钥,因此存在设置值

我想出了以下内容,但它看起来过于冗长.

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)))
    }
  })
}
Run Code Online (Sandbox Code Playgroud)

实现这一目标的更简单/更清晰的方法是什么?

谢谢!

Tom*_*icz 5

这个用例很常见,有一个内置的方法:

tasks groupBy {_.assignee}
Run Code Online (Sandbox Code Playgroud)

groupBy但是会Map[String,List[Task]]在你想要的时候回来.Map[String, Set[String]].这应该这样做:

groupBy {_.assignee} mapValues {_ map {_.description} toSet}
Run Code Online (Sandbox Code Playgroud)

groupBYnull友好的,但你不应该.Option[String]是更好,更惯用.