【问题标题】:Refactoring java style to more functional scala style将 java 风格重构为更具功能性的 scala 风格
【发布时间】:2016-08-09 15:29:49
【问题描述】:

我想将用户到他们朋友的地图转换为朋友到他们朋友的地图。 输入用户名:字符串 因此,通过将每个 List[User] 设为键,将 Map[Username, List[User]] 映射到 Map[Username, List[Username]]。

我下面的代码非常类似于 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

而新建一个列表缓冲区和追加将如何完成?

【问题讨论】:

  • 换句话说,你想达到什么目的?
  • 我想用更多的函数风格转换代码。
  • 尝试类似“我将名称作为字符串,每个名称都指向带有地图的相应朋友的列表 [字符串],我正在尝试计算
  • 凉风你接受答案了吗?
  • @Alec 我用一些措辞更新了我的问题。

标签: scala


【解决方案1】:

也许你会喜欢

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

【讨论】:

  • 这对你有用吗? groupBy(_._1.username) 是如何转换成地图的?
  • 方法组通过将元素分组到Map[String,Seq[T]],其中 T 是Friend -&gt; User。这里key是参数中指定的值,values是源数据中元素的序列
  • 参数_._1是从Friend -&gt; User得到Friend_._1.username 取值来自 Friend 的分组
猜你喜欢
  • 1970-01-01
  • 2017-11-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-20
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
相关资源
最近更新 更多