简洁但可读的计算地图的方法?

时间:2011-10-19 09:49:47

标签: scala

鉴于,

case class User(name: String, roles: List[String])
val users: List[User] = ...

我想计算一张地图 -

val roleToUsers: Map[String, List[User]] = ???

我可以简洁地说:

(for (user <- users; role <- user.roles) yield (role, user)).groupBy(_._1).mapValues(_.map(_._2))

但是下划线让我觉得有点太神秘了。是否有一种更简洁的方法来做到这一点并不会让它变得更加冗长?

修改: List[Role] - &gt; List[User]

2 个答案:

答案 0 :(得分:1)

您可以使用与case的模式匹配来更明确地命名参数:

(for { user <- users; role <- user.roles } yield (role, user)) groupBy
     { case (role, _) => role } mapValues
        { roleUser => roleUser map { case (_, user) => user} }

它不会更长,更清晰,特别是如果分成几行。在上文中,_仅用于表示“不关心”,但您也可以将所有内容命名为完全避免_

(for { user <- users; role <- user.roles } yield (role, user)) groupBy
     { case (role, user) => role } mapValues
        { roleUser => roleUser map { case (role, user) => user} }

答案 1 :(得分:1)

也许这个:

val lst = for {
  user <- users
  role <- user.roles
} yield (role, users collect {
  case user if user.roles contains role => user.name
})
val map = lst.toMap

或者,没有理解和小优化

users.flatMap(_.roles).distinct.map(role => 
  (role, users collect { 
    case user if user.roles contains role => user.name })).toMap