Order List of Case Classes

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Order List of Case Classes

Kai_Meder
Hi,

I have a list of CaseClasses and want to sort them like:
Every QueryMovieTask, which has a Some(year) first and then
order by length of query-string: Longest queries first.


case class QueryMovieTask(val query: String, val year: Option[Int])

def sorter(a: QueryMovieTask, b: QueryMovieTask) = {
       
        var aLength  = 0
        var aHasYear = false

        var bLength  = 0
        var bHasYear = false

        a match {
          case QueryMovieTask(q, Some(_)) => {
                aLength  = q.length
                aHasYear = true
          }
          case QueryMovieTask(q, None) => {
                aLength = q.length
                aHasYear = false
          }
        }

        b match {
          case QueryMovieTask(q, Some(_)) => {
                bLength  = q.length
                bHasYear = true
          }
          case QueryMovieTask(q, None) => {
                bLength = q.length
                bHasYear = false
          }
        }
       
        (aHasYear && !bHasYear) || (aLength > bLength)
   }

list.sort( sorter )

Is there a short way to determine whether the QueryMovieTask has a Some
or None year?

Any way to do this (much) more compact/elegant?

thanks,
Kai
Reply | Threaded
Open this post in threaded view
|

Re: Order List of Case Classes

Aaron Harnly-2-2
Hi Kai,

On Nov 30, 2009, at 3:57 AM, Kai Meder wrote:
> I have a list of CaseClasses and want to sort them like:
> Every QueryMovieTask, which has a Some(year) first and then
> order by length of query-string: Longest queries first.

This seems to do what you want:

scala> List(q1,q2,q3,q4).sort { (a, b) => (a.year.isDefined && b.year.isEmpty)  || a.query.length > b.query.length  }.foreach { q => println(q) }
QueryMovieTask(bb,Some(1))
QueryMovieTask(a,Some(1))
QueryMovieTask(bb,None)
QueryMovieTask(a,None)

With 2.8, sequences have the convenient .sortBy method, which sorts on extracted keys (aka the Schwartzian transform):

scala> List(q1,q2,q3,q4).sortBy { q => (q.year.isEmpty, -1 * q.query.length) }.foreach { q => println(q) }
QueryMovieTask(bb,Some(1))
QueryMovieTask(a,Some(1))
QueryMovieTask(bb,None)
QueryMovieTask(a,None)

cheers,
~aaron