将java样式重构为更多功能的scala样式

时间:2016-08-09 15:29:50

标签: scala

我想将用户地图转换为他们的朋友,将朋友地图转换为他们的朋友。 类型用户名:字符串 因此,通过将每个列表[用户]放入密钥,将[用户名,列出[用户]]映射到[用户名,列出[用户名]]。

我在下面的代码中非常类似于java,我想重构它以使它更具有idomatic scala代码。

val map: Map[String, List[User]] = {
  var m  = collection.mutable.Map[String, collection.mutable.ListBuffer[User]]()
  for(user <- users) {
    for(friend <- user.Friends) {
      if (m.contains(friend)) {
        //m.get(friend.username) += user
      } else {
        m += (friend -> collection.mutable.ListBuffer[User]())
        //m.get(friend.username) += user
      }
    }
  }
  m.map{e =>
    (e._1 -> e._2.toList)}.toMap
}

我开始尝试这个:

users.map( user =>
  user.friends.flatMap(friend =>

)

作为附注,我如何附加到ListBuffer,由于某种原因这对我不起作用:

m.get(friend.username) += user

对于新手一个listbuffer和追加会怎么做?

1 个答案:

答案 0 :(得分:2)

也许你想要

    val map: Map[String, List[User]] = {
        val m = new collection.mutable.HashMap[String, collection.mutable.Set[User]]() with scala.collection.mutable.MultiMap[String, User]
        for {
            user <- users
            friend <- user.Friends
        }   m.addBinding(friend.username,user)

        m.mapValues(x ⇒ x.toList).toMap
    }

第二个问题:方法m.get(friend.username)返回Option [ListBuffer [User]]。选项不包含+ =。

更新

一线解决方案

    val map: Map[String, Seq[User]] = {
        users.flatMap(user ⇒ user.Friends.map(_ → user)).groupBy(_._1.username).mapValues(_.map(_._2))
    }