Матч по паре равных значений

Я пытаюсь обработать кортеж, где один из случаев состоит в том, что оба значения равны. Есть ли лучший, более сжатый способ match на этом, чем

(p, q) match {
  case (p, q) if (p == q) => println("Match!")
  ...
}

?

Ответ 1

Лично я думаю, что вы сделали это отлично, потому что это просто, понятно и понятно читателю, что происходит.

Итак, здесь вы можете сделать это без предложения if. Вы могли бы просто соответствовать версии с заменой, используя backticks, чтобы превратить q в стабильные идентификаторы. Как отметил @Luigi, вы можете просто проверить, что p соответствует q:

  (p, q) match {
    case (`q`, _) => println("Match!")
    ...
  }

Вот так:

def f(p: Int, q: Int) {
  (p, q) match {
    case (`q`, _) => println("Match!")
    case _ => println("No")
  }
}

f(1, 2)   // "No"
f(1, 1)   // "Match!"

Ответ 2

Вы можете определить свой собственный экстрактор:

object Eq {
   def unapply[T](pair:(T,T)):Option[T] = 
      if (pair._1 == pair._2) Some(pair._1) else None
}

Затем (4,4) match { case Eq(n) => println("same: " + n) } выводит same: 4, а (3,4) не соответствует.

В моем блоге я перечислил некоторые экстракторы сравнения (извините, это на немецком языке).

Ответ 3

Вы можете поменять местами значения, а затем сравнить кортеж с его обычным равным методом:

scala> val t = (1, 1)
t: (Int, Int) = (1,1)

scala> t.swap == t
res0: Boolean = true

scala> val t = (1, 2)
t: (Int, Int) = (1,2)

scala> t.swap == t
res1: Boolean = false