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

时间:2013-01-20 11:54:39

标签: scala collections grouping

注意我已经退出了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)

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

  • 地图没有(咳嗽)友好(咳嗽) null 键(我使用Option [String]为受让人解决了这个问题)和
  • 必须区分地图中是否已存在密钥(仅添加现有集合的值)与已添加的密钥,因此存在设置值

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

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)))
    }
  })
}

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

谢谢!

1 个答案:

答案 0 :(得分:5)

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

tasks groupBy {_.assignee}

groupBy但是在您需要Map[String,List[Task]]时会返回.Map[String, Set[String]]。这应该这样做:

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

groupBYnull - 友好,但你不应该。 Option[String]更好,也更惯用。