cool breeze cool breeze - 1 year ago 114
Scala Question

Refactoring java style to more functional scala style

I want to transform a map of users to their friends to a map of friends to their friends.
type Username: String
So Map[Username, List[User]] to Map[Username, List[Username]] by making each List[User] into the key.

I have the following code below that is very java like that I want to refactor to make it more idomatic scala code.

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
}{e =>
(e._1 -> e._2.toList)}.toMap

I started off trying this: user =>
user.friends.flatMap(friend =>


As a side note, how do I append to a ListBuffer, for some reason this was not working for me:

m.get(friend.username) += user

And to new-up a listbuffer and append would be done how?

Answer Source

Maybe you would like

    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

And second question: method m.get(friend.username) returns Option[ListBuffer[User]]. Option not contains +=.


One line solution

    val map: Map[String, Seq[User]] = {
        users.flatMap(user ⇒ → user)).groupBy(_._1.username).mapValues(
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download