0
votes

There is a snippet of scala code,which I think quite easy

val m1 = Map("age"->60,"name"->"x")
val m2 = Map("age"->99,"name"->"j")
val l = List(m1,m2)
val max = l.maxBy(_("age"))

However, instead of the expecting result val m2 = Map("age"->99,"name"->"j") I get an error:

<console>:13: error: No implicit Ordering defined for Any.

I know there is something wrong about the implicit parameter,but I don't know how to solve this problem.

update further,suppose I need a more general solution for this,a function

def max(l:List[Map[String,Any]],key:String)

then max(l,"age") == Map("age"->99,"name"->"j") max(l,"name") == Map("age"->60,"name"->"x")

4

4 Answers

4
votes

Your maps have type Map[String, Any] so compiler could not find Ordering for Any object. Add explicit conversion to Int:

val max = l.maxBy(_("age").asInstanceOf[Int])

Or try use Map with specific value's type such as Map[String, Int] or similar.

Other way is to use case classes or tuples:

val list = List((60, "j"), (99, "x"))
list.maxBy(_._1)
0
votes

This works,

l.maxBy(m => m("age").toString.toInt)

and is closer to intended semantics on maximal (numerical) age, even that it does not prove type-safe, the original maps type preserves no information on the intended types, as aforementioned.

0
votes

Try Using last line as val max = l.maxBy(_("age").toString.toInt)

0
votes

Something like this may work (not that I like the idea of Map[String, Any]):

def myOrder(k: String) = { 
  x: Map[String, Any] => 
    x(k) match { case i:Int => (i, "") 
                 case s:String => (0, s) } 
}

l.maxBy(myOrder("age")) // Map(age -> 99, name -> j)
l.maxBy(myOrder("name")) // Map(age -> 60, name -> x)