3

(请注意,我对 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)

我想要一个 Map ,其中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)))
    }
  })
}

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

谢谢!

4

1 回答 1

5

这个用例非常常见,因此有一个内置方法:

tasks groupBy {_.assignee}

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

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

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

于 2013-01-20T12:02:51.723 回答