4

I've got a query result of List[(Int,String,Double)] that I need to convert to a Map[String,String] (for display in an html select list)

My hacked solution is:

val prices = (dao.getPricing flatMap {
  case(id, label, fee) =>
    Map(id.toString -> (label+" $"+fee))
  }).toMap

there must be a better way to achieve the same...

kiritsuku
  • 52,967
  • 18
  • 114
  • 136
virtualeyes
  • 11,147
  • 6
  • 56
  • 91

2 Answers2

9

How about this?

val prices: Map[String, String] =
  dao.getPricing.map {
    case (id, label, fee) => (id.toString -> (label + " $" + fee))
  }(collection.breakOut)

The method collection.breakOut provides a CanBuildFrom instance that ensures that even if you're mapping from a List, a Map is reconstructed, thanks to the type annotation, and avoids the creation of an intermediary collection.

Jean-Philippe Pellet
  • 59,296
  • 21
  • 173
  • 234
  • 1
    +1. odd, what on earth is collection.breakout? ;-) I like that Map has been removed from the map{} block, but now it's been added to the return type ;-(, compiler inference rocks, no like type type type, that's for Java people ;-) – virtualeyes May 28 '12 at 13:34
  • 1
    @virtualeyes Either you write toMap and you have to create an intermediary collection, or you use `breakOut` with the type annotation. – Jean-Philippe Pellet May 28 '12 at 13:44
  • @Jean-Phillipe ah ok, so my approach is not only poor, but inefficient as well ;-) No big deal here, pricing consists of a handful of records, any which way does the trick, was just looking for a cleaner solution than what I had hacked together – virtualeyes May 28 '12 at 13:44
8

A little more concise:

val prices =
  dao.getPricing.map { case (id, label, fee) => ( id.toString, label+" $"+fee)} toMap

shorter alternative:

val prices =
  dao.getPricing.map { p => ( p._1.toString, p._2+" $"+p._3)} toMap
Johnny Everson
  • 8,343
  • 7
  • 39
  • 75
  • there you go, nice one, +1, plus a prize, concision is king – virtualeyes May 28 '12 at 13:39
  • 1
    +1 for first alternative, -1 to the second ... giving things names is at *lot* more readable than p._1 etc. (Although virtualeyes might consider making the dao return a Pricing case class rather than using a triple, in which case the second option would be fine). – Matt R May 28 '12 at 13:43
  • I agree, I prefer it, too. Just added for reference. – Johnny Everson May 28 '12 at 13:43
  • @MattR you're right, using ScalaQuery, could just as well return a case class instance, but thought I'd explore tuples (since vast majority of query results are cast to case class instances, quite convenient) – virtualeyes May 28 '12 at 13:47
  • @MattR I switched to case class instance, the cleanest approach, and minimal extra overhead compared to returning a tuple subset – virtualeyes May 28 '12 at 14:13
  • @virtualeyes Cool! YMMV, but my personal style rule is to always use case classes instead of tuples with arity > 2 (with the possible exception when all uses fit within a single editor screen). – Matt R May 28 '12 at 18:01
  • @MattR I have yet to use tuple based query results at all, this question was a failed experiment in that respect as I am back to case class instances ;-) Of course, yes, when querying for a field or 2, tuples make sense. ScalaQuery, btw, completely rocks – virtualeyes May 28 '12 at 18:05