Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create an lookup Map in Scala

While I know there's a few ways to do this, I'm most interested in finding the most idiomatic and functional Scala method.

Given the following trite example:

case class User(id: String)
val users = List(User("1"), User("2"), User("3"), User("4")) 

What's the best way to create an immutable lookup Map of user.id -> User so that I can perform quick lookups by user.id.

In Java I'd probably use Google-Collection's Maps.uniqueIndex although its unique property I care less about.

like image 666
Ben Smith Avatar asked Jul 25 '11 23:07

Ben Smith


2 Answers

You can keep the users in a List and use list.find:

users.find{_.id == "3"} //returns Option[User], either Some(User("3")) or None if no such user

or if you want to use a Map, map the list of users to a list of 2-tuples, then use the toMap method:

val umap = users.map{u => (u.id, u)}.toMap

which will return an immutable Map[String, User], then you can use

umap contains "1" //return true

or

umap.get("1") //returns Some(User("1"))
like image 121
Dan Simon Avatar answered Oct 05 '22 13:10

Dan Simon


If you're sure all IDs are unique, the canonical way is

users.map(u => (u.id, u)).toMap

as @Dan Simon said. However, if you are not sure all IDs are unique, then the canonical way is:

users.groupBy(_.id)

This will generate a mapping from user IDs to a list of users that share that ID.

Thus, there is an alternate not-entirely-canonical way to generate the map from ID to single users:

users.groupBy(_.id).mapValues(_.head)

For expert users who want to avoid the intermediate step of creating a map of lists, or a list which then gets turned into a map, there is the handy scala.collecion.breakOut method that builds the type that you want if there's a straightforward way to do it. It needs to know the type, though, so this will do the trick:

users.map(u => (u.id,u))(collection.breakOut): Map[String,User]

(You can also assign to a var or val of specified type.)

like image 28
Rex Kerr Avatar answered Oct 05 '22 12:10

Rex Kerr