Краткий, но читаемый способ расчета карты? - PullRequest
0 голосов
/ 19 октября 2011

Учитывая,

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] -> List[User]

Ответы [ 2 ]

1 голос
/ 21 октября 2011

Может быть, это:

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
1 голос
/ 20 октября 2011

Вы можете использовать сопоставление с шаблоном с 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} }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...