2

quite often I have code like the following

if (operator == Equal || operator == Missing || operator == Unknown) {

To make it less verbose and a little bit more readable sometimes I issue:

if (List(Equal, Missing, Unknown).contains(operator)) {

I know I could also issue pattern matching, like this

operator match {
  case Equal | Missing | Unknown => {

which brings another level of nesting braces

I was wondering if there's some kind of method like

if (operator.isOneOf(List(Equal, Missing, Unknown))) {

--

edit:

to show how to use the different options that appeared here:

Using Set as a function

if (Set(1, 2, 3)(3)) {
  "Gotcha"
} else {
  "no luck..."
}

Using PartialFunction.cond

import PartialFunction.cond

if (cond(3) { case 1 | 2 | 3 => true }) {
  "Gotcha"
} else {
  "no luck..."
}

Implementing isOneOf

class ComparableWithIsOneOf[T](val value: T) {
  def isOneOf(values: T*): Boolean = {
    values.contains(value)
  }
}
object Comparison {
  object implicits {
    implicit def AnyToComparableWithIsOneOf[T](value: T): ComparableWithIsOneOf[T] = {
      return new ComparableWithIsOneOf(value)
    }
  }
}

import Comparison.implicits._

if (3.isOneOf(1, 2, 3)) {
  "Gotcha"
} else {
  "no luck..."
}

In the end I like the Set() version better, but I think the best is to stick with pattern matching, is more standard and idiomatic...

opensas
  • 60,462
  • 79
  • 252
  • 386

4 Answers4

4

You could just write

if (Set(Equal, Missing, Unknown)(operator)) { ...

Set being a function etc...

Luigi Plinge
  • 50,650
  • 20
  • 113
  • 180
2

We also can pimp your pattern matching solution witn cond or condOpt defined in PartialFunction:

condOpt(operator) { case Equal | Missing | Unknown =>  ... }
Community
  • 1
  • 1
om-nom-nom
  • 62,329
  • 13
  • 183
  • 228
2

Write it by yourself:

scala> implicit class IsOneOf[A](a: A) { def isOneOf(as: A*) = as contains a }
defined class IsOneOf

scala> trait Trait
defined trait Trait

scala> case object Equal extends Trait
defined module Equal

scala> case object Missing extends Trait
defined module Missing

scala> case object Unknown extends Trait
defined module Unknown

scala> case object Else extends Trait
defined module Else

scala> def test(t: Trait) = t.isOneOf(Equal, Missing, Unknown)
test: (t: Trait)Boolean

scala> test(Missing)
res25: Boolean = true

scala> test(Else)
res26: Boolean = false

This is also typesafe:

scala> 1.isOneOf("")
<console>:12: error: type mismatch;
 found   : String("")
 required: Int
              1.isOneOf("")
                        ^
kiritsuku
  • 52,967
  • 18
  • 114
  • 136
  • thanks, you gave me a couple of ideas to start it (pls have a look at my solution), but I'm getting ":19: error: `implicit' modifier can be used only for values, variables and methods"... what version of scala are you using? I'm with 2.9.1.final – opensas Sep 16 '12 at 17:31
  • 1
    @opensas [implicit class](http://docs.scala-lang.org/sips/pending/implicit-classes.html) was introduced in 2.10 – om-nom-nom Sep 16 '12 at 17:35
0

I tried to implement it and this is what I got

First I define a generic class with the isOneOf method, like this

class ComparableWithIsOneOf[T](val value: T) {
  def isOneOf(values: T*): Boolean = {
    values.contains(value)
  }
}

Then I define an implicit converter (the double nesting Comparison.implicits is just to make the imports easier...)

object Comparison {
  object implicits {
    implicit def AnyToComparableWithIsOneOf[T](value: T): ComparableWithIsOneOf[T] = {
      return new ComparableWithIsOneOf(value)
    }
  }
}

to use it, I just issue:

import Comparison.implicits._

if (3.isOneOf(1, 2, 3)) {
  "Gotcha"
} else {
  "no luck..."
}

It wasn't that much code, and the result is typesafe

anyway, I think it's better to use pattern matching, I feel like it's more idiomatic...

opensas
  • 60,462
  • 79
  • 252
  • 386