Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!")
  ...
}

?

like image 326
Péter Török Avatar asked Sep 30 '12 20:09

Péter Török


3 Answers

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!"
like image 61
dhg Avatar answered Nov 18 '22 02:11

dhg


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).

like image 7
Landei Avatar answered Nov 18 '22 01:11

Landei


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
like image 6
kiritsuku Avatar answered Nov 18 '22 02:11

kiritsuku