在Scala中,有一种简洁的方法可以将一个值与多个值进行比较

Gig*_*ron 17 scala equality

假设我有一个变量x,我想检查它是否等于多个值a,b,c,d,e中的任何一个(我的意思是==相等,而不是同一性).

在SQL查询中,处理相同的概念

WHERE x IN (a, b, c, d, e).
Run Code Online (Sandbox Code Playgroud)

在Scala中是否有类似的东西那么简单?我知道它可以在一行中使用复杂的表达式来构建,例如构建HashSet并检查集合中是否存在,但我更喜欢使用简单的构造(如果它可用).

mis*_*tor 24

您可以in按如下方式实现运算符:

scala> implicit def anyWithIn[A](a: A) = new {
     |   def in(as: A*) = as.exists(_ == a)
     | }
anyWithIn: [A](a: A)java.lang.Object{def in(as: A*): Boolean}

scala> 5 in (3, 4, 9, 11)
res0: Boolean = false

scala> 5 in (3, 4, 9, 11, 5)
res1: Boolean = true
Run Code Online (Sandbox Code Playgroud)

  • 那很华丽.直接进入我自己的标准扩展集,最终在我的所有项目中,并且可以说是标准库包含 (2认同)

Fra*_*mas 22

我宁愿contains(a)exists(_ == a):

scala> List(3, 4, 5) contains 4
res0: Boolean = true

scala> List(3, 4, 5) contains 6
res1: Boolean = false
Run Code Online (Sandbox Code Playgroud)

更新:contains定义在SeqLike,所以上面的任何序列都适用.

更新2:以下是containsin 的定义SeqLike:

def contains(elem: Any): Boolean = exists (_ == elem)
Run Code Online (Sandbox Code Playgroud)


oxb*_*kes 12

鉴于a Set[A]也是a A => Boolean,你可以说:

Set(a, b, c, d, e) apply x
Run Code Online (Sandbox Code Playgroud)

为此定义一些pimpin'糖实际上非常好:

class PredicateW[A](self : A => Boolean) {
  def ?:(a : A) = self apply a
}
implicit def pred2wrapper[A](p : A => Boolean) = new PredicateW(p)
Run Code Online (Sandbox Code Playgroud)

然后你可以这样编写代码:

x ?: Set(a, b, c, d, e)
Run Code Online (Sandbox Code Playgroud)

  • 另一个简洁的解决方案,谢谢.但我的美国键盘上没有'∈'符号! (2认同)

Mal*_*lio 9

通过综合所有其他答案,我得出了正确的答案:

implicit def anyWithIn[A](a: A) = new {
    def ?(as: A*) = as.contains(a)
}
anyWithIn: [A](a: A)java.lang.Object{def ?(as: A*): Boolean}

5 ? (1,3,5)
res1: Boolean = true
Run Code Online (Sandbox Code Playgroud)

当当.


use*_*own 5

存在:

 List (3, 4, 5).exists (_ == 4)
 // res20: Boolean = true
Run Code Online (Sandbox Code Playgroud)

找到并过滤得很近:

List (3, 4, 5).find (_ == 4)
// res16: Option[Int] = Some(4)
List (3, 4, 5).filter (_ == 4)
// res17: List[Int] = List(4)
Run Code Online (Sandbox Code Playgroud)

我的第一个答案是,作为其他答案,使用包含:

List (3, 4, 5).contains (4)
Run Code Online (Sandbox Code Playgroud)

但后来我想,它只适用于像4这样的盒装值,不适用于区分身份和平等的类.为了证明这一点,我写了一个小班,这证明错了::)

class Ue (val i: Int) { 
  override def equals (other: Any) = other match {
    case o: Ue => i == o.i
    case _ => false }
}

val a = new Ue (4)
// a: Ue = Ue@1e040e5
val b = new Ue (4)
// b: Ue = Ue@1a4548b (no identity)
a == b
// res110: Boolean = true (surprise?) 
a.equals (b)
// res112: Boolean = true (expected)
a.eq (b)
// res113: Boolean = false (expected) 
List (a).contains (b)    
// res119: Boolean = true (surprise)
List (a).exists (_ == b) 
// res120: Boolean = true (expected) 
List (a).exists (_ .eq (b)) 
// res121: Boolean = false (expected) 
Run Code Online (Sandbox Code Playgroud)

我明白了,我必须经常使用equals/eq/==来区分我的大脑.

List (3, 4, 5).contains (4)
Run Code Online (Sandbox Code Playgroud)

是最简单的答案.