0

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)

Aryan Firouzian
  • 1,940
  • 5
  • 27
  • 41

4 Answers4

2

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
Jasper-M
  • 14,966
  • 2
  • 26
  • 37
  • I had a json file, which is parsed to list of *Some[Long]*. You are right, it works for *Option[Long]*. This is so confusing :D I need to study some basics. – Aryan Firouzian Dec 31 '17 at 14:54
  • Which library parses it to a `Some[Long]`? If you statically know it's always going to be a `Some` it doesn't make sense to have the extra level of boxing. – Jasper-M Dec 31 '17 at 14:57
  • I used *parseFull* from *scala.util.parsing.json._* and it doesn't make sense to always get *Some*. Do you have any suggestion in your mind? – Aryan Firouzian Dec 31 '17 at 15:08
  • 2
    I'm no expert in the JSON parsing domain, but I think scala.util.parsing.json is a deprecated API because it was never really meant for production usage. – Jasper-M Dec 31 '17 at 15:26
1
longSomeList.collect { case Some(n) => n }.max
Sebastian
  • 16,813
  • 4
  • 49
  • 56
1

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.

Dima
  • 39,570
  • 6
  • 44
  • 70
1

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)
nicodp
  • 2,362
  • 1
  • 11
  • 20