Péter Török
Péter Török

Reputation: 116266

Match on a pair of equal values

I am trying to process a tuple, where one of the cases is that the two values are equal. Is there a better, more concise way to match on this than

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

?

Upvotes: 10

Views: 2794

Answers (3)

dhg
dhg

Reputation: 52681

Personally, I think the way you've done it is great because it's simple, intuitive, and clear to the reader what's going on.

That said, here's one way you could do it without an if clause. You could just match on the swapped version, using backticks to turn q into stable identifiers. As @Luigi pointed out, you can just check that p matches q:

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

Like this:

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

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

Upvotes: 22

Landei
Landei

Reputation: 54584

You can define your own extractor:

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

Then (4,4) match { case Eq(n) => println("same: " + n) } prints same: 4, while (3,4) wouldn't match.

I listed some comparision extractors in my blog (sorry, it's in German).

Upvotes: 7

kiritsuku
kiritsuku

Reputation: 53348

You can swap the values and then compare the tuple with its normal equals-method:

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

Upvotes: 6

Related Questions