Сравните перечисляемые значения, которые не могут быть отсортированы - PullRequest
0 голосов
/ 06 ноября 2019

Мне нужно сравнить перечисляемые значения, но набор этих значений не упорядоченный .

У меня есть значения Rock,Paper,Scissors, и я хочу, чтобы Rock теряет более Paper например. Этого не происходит, см. Последние две строки кода

object Move extends Enumeration {
    type Move = Value
    val Rock, Paper, Scissors = Value
}
import Move._

object MoveOrdering extends Ordering[Move] {
    def compare(m1: Move, m2: Move) = {
        (m1, m2) match {
            case (Rock, Paper) => -1
            case (Rock, Scissors) => +1
            case (Paper, Rock) => +1
            case (Paper, Scissors) => -1
            case (Scissors, Paper) => +1
            case (Scissors, Rock) => -1
            case _ => 0
        }
    }
}

Rock > Scissors // evaluates to false, I'd expect true
Scissors < Rock // evaluates to false, I'd expect true

Чего мне не хватает, что делает приведенный выше код не работающим как положено?

1 Ответ

4 голосов
/ 06 ноября 2019

Я думаю, вы ожидаете, что вместо Rock > Scissors будет рассмотрено MoveOrdering.

Хорошо, вот как это будет работать, потому что abstract class Value extends Ordered[Value] с реализацией по умолчанию как:

 abstract class Value extends Ordered[Value] with Serializable {
    /** the id and bit location of this enumeration value */
    def id: Int
    /** a marker so we can tell whose values belong to whom come reflective-naming time */
    private[Enumeration] val outerEnum = thisenum

    override def compare(that: Value): Int =
      if (this.id < that.id) -1
      else if (this.id == that.id) 0
      else 1

Таким образом, по умолчанию он использует index элемента, определенного в перечислении. В вашем случае по умолчанию Rock < Paper < Scissors. Если вы хотите использовать индивидуальный заказ:

object Move extends Enumeration{
  type Move = Value
  val Paper, Scissors, Rock = Value
}
import Move._
implicit object MoveOrdering extends Ordering[Move] {
  def compare(m1: Move, m2: Move) = {
    (m1, m2) match {
      case (Rock, Paper) => -1
      case (Rock, Scissors) => +1
      case (Paper, Rock) => +1
      case (Paper, Scissors) => -1
      case (Scissors, Paper) => +1
      case (Scissors, Rock) => -1
      case _ => 0
    }
  }
}

implicit val o = implicitly[Ordering[Move]]

println(List(Rock, Scissors, Paper).sorted)
println(o.lt(Rock, Scissors))
...