Получите максимум в ListBuffer of Some[Long] в Scala

Этот фрагмент кода работает нормально и возвращает 343423, как и ожидалось:

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

Но это не работает для некоторых [Long]:

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

Ошибка: для Some[Long] не определено неявное упорядочение.
val maxSomeLong = longSomeList.max

Есть ли простое решение, чтобы получить максимум из второго списка?

функция max из TraversableForwarder(scala.collection.generic)

4 ответа

Решение

Ты ищешь .flatten,

 longSomeList.flatten.max

Или дайте ему порядок использования явно:

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

Кроме того, не используйте изменяемые коллекции.

В каком реальном сценарии вы бы ListBuffer[Some[Long]]? Вы могли бы также иметь ListBuffer[Long] затем.

Это работает:

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

Проблема в том, что вы пытаетесь заказать элементы типа Some[Long], который не определен. Итак, вы говорите компилятору, чтобы он знал, как их заказать:

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

Что вы можете сделать, это либо развернуть Someс, чтобы получить Longs

longSomeList.flatten.max

или определить ваше неявное упорядочение аналогичным образом:

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

а потом:

scala> longSomeList.max
res12: Some[Long] = Some(343423)
Другие вопросы по тегам