0
votes

This piece of code works fine and returns 343423 as expected:

val longList: ListBuffer[Long] = ListBuffer(103948,343423,209754)
val maxLong = longList.max

But it doesn't work for Some[Long]:

val longSomeList: ListBuffer[Some[Long]] = ListBuffer(Some(103948),Some(343423),Some(209754))
val maxSomeLong = longSomeList.max

Error: No implicit Ordering defined for Some[Long].
val maxSomeLong = longSomeList.max

Is there any simple solution to get the max of the second list?

max function from TraversableForwarder(scala.collection.generic)

4

4 Answers

1
votes

You are looking for .flatten.

 longSomeList.flatten.max

Or give it the ordering to use explicitly:

 longSomeList
   .max(Ordering.by[Option[Int], Int](_.getOrElse(Int.MinValue)))

Also, don't use mutable collections.

2
votes

In which real world scenario would you have a ListBuffer[Some[Long]]? You could just as well have a ListBuffer[Long] then.

This works:

val longSomeList: ListBuffer[Option[Long]] = ListBuffer(Some(103948),Some(343423),Some(209754))
val maxSomeLong = longSomeList.max
1
votes
longSomeList.collect { case Some(n) => n }.max
1
votes

The problem is you are trying to order elements of type Some[Long], which is not defined. So you are telling the compiler to know how to order these:

scala> Some(1) < Some(2)
<console>:8: error: value < is not a member of Some[Int]
              Some(1) < Some(2)
                      ^

What you can do is either unwrap the Somes to get the Longs

longSomeList.flatten.max

or to define your implicit ordering likewise:

implicit object Ord extends Ordering[Some[Long]] {
  def compare(a: Some[Long], b: Some[Long]) = a.getOrElse(Long.MinValue) compare b.getOrElse(Long.MinValue)
}

and then:

scala> longSomeList.max
res12: Some[Long] = Some(343423)