Fork me on GitHub

Hacking Scala

#scala #hacking

April 28, 2013 at 12:46am

Essential Scala Collection Functions

Let me ask you a question. How many times you wrote similar code?

case class User(id : Int, userName: String)

val users: List[User] = // ....
val resultUsers: List[User] = // ....

for (i <- 0 until users.size) {
    if (users(i).userName != "test") {
        resultUsers += users(i)
    }
}

May imperative languages like Java, C, C++ have very similar approach for iteration. Some of them have some syntactic sugar (like Java for each loop). There are many problems with this approach. I think the most important annoyance is that it’s hard to tell, what this code actually does. Of course, if you have 10+ years Java experience, you can tell it within a second, but what if the body of the for is more involving and has some state manipulatin? Let me show you another example:

def formatUsers(users: List[User]): String = {
    val result = new StringBuilder 

    for (i <- 0 until users.size) {
        val userName = users(i).userName

        if (userName != "test") {
            result append userName

            if (i < users.size - 1) {
                result append ", "
            }
        }
    }

    return result.toString
}

Was it easy to spot the purpose of this code? I think more important question: how do you read and try to understand this code? In order to understand it you need to iterate in your head - you create simple trace table in order to find out how values of i and result are changing with each iteration. And now the most important question: is this code correct? If you think, that it is correct, then you are wrong! It has an error, and I leave it to you to find it. It’s pretty large amount of code for such a simple task, isn’t it? I even managed to make an error it.

I’m going to show you how this code can be improved, so that intent is more clear and a room for the errors is much smaller. I’m not going to show you complete Scala collection API. Instead I will show you 6 most essential collection functions. These 6 function can bring you pretty far in your day-to-day job and can handle most of your iteration needs. I going to cover following functions: filter, map, flatMap, foldLeft, foreach and mkString.

Also note, that these functions will work on any collection type like List, Set or even Map (in this case they will work on tuple (key, value))

Keep reading