Scala - сортировка по необязательным полям, с последним значением None - PullRequest
2 голосов
/ 29 января 2020

У меня есть следующий класс:

final case class PowerDetails (
  [...],
  label: String,
  title: String,
  category: String,
  idCategory: Option[String],
  numCategory: Option[Int]
)

Мне нужно отсортировать список PowerDetails следующим образом:

Элементы, имеющие значение для idCategory и numCategory должно быть до None, а заказано idCategory и затем numCategory. Что касается значений None, их необходимо упорядочить по полям category, title, label.

Если возможно, я бы хотел избежать расширения Ordered

final case class PowerDetails (

   ...

) extends Ordered[PowerDetails] {

    override def compare(that: PowerDetails): Int = {
       // Define here the comparison
    }

}

Я попытался создать Порядок, как показано ниже, и затем использовать функцию sorted, но я получение NullPointerException

  implicit val orderingPowers = optionOrdering.thenComparing(ordering)

  val ordering: Ordering[PowerDetails] = Ordering[(String, String, String)]
    .on[PowerDetails](powerDetail =>
      ( powerDetail.category, powerDetail.title, powerDetail.label))

  val optionOrdering : Ordering[PowerDetails] = Ordering[(Option[String], Option[Int])]
    .on[PowerDetails](powerDetail =>
      (powerDetail.idCategory, powerDetail.numCategory))

Не могли бы вы помочь мне узнать, как это сделать? Спасибо.

Ответы [ 2 ]

3 голосов
/ 29 января 2020

Вот еще один подход, использующий Ordering.by вместе с опцией isEmpty, используя false < true для требуемого Some/None заказа:

final case class PowerDetails (
  field1: String,
  field2: Int,
  label: String,
  title: String,
  category: String,
  idCategory: Option[String],
  numCategory: Option[Int]
)

implicit val PDOrderer: Ordering[PowerDetails] = Ordering.by{
  case PowerDetails(_, _, label, title, cat, idCat, numCat) =>
    (idCat.isEmpty, idCat, numCat.isEmpty, numCat, cat, title, label)
}
2 голосов
/ 29 января 2020

Будет ли это работать для вас?

implicit val PDOrd :Ordering[PowerDetails] = Ordering.by(
  pd => (pd.idCategory.getOrElse("~~~~")
       , pd.numCategory.getOrElse(Int.MaxValue)
       , pd.category
       , pd.title
       , pd.label ))

По общему признанию "~~~~" не конец вселенной String, но это должно работать в большинстве случаев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...