假设我有一个变量x,我想检查它是否等于多个值a,b,c,d,e中的任何一个(我指的是==相等,而不是恒等式)。在SQL查询中,使用
WHERE x IN (a, b, c, d, e).
Scala中有没有类似的东西可以这么简单呢?我知道可以用一个复杂的表达式在一行中完成,比如构建一个HashSet并检查集合中是否存在,但是如果可以的话,我更喜欢使用一个简单的结构。
iibxawm41#
您可以按如下方式实现in运算符:
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
wnvonmuf2#
我更喜欢contains(a)而不是exists(_ == a):
contains(a)
exists(_ == a)
scala> List(3, 4, 5) contains 4 res0: Boolean = true scala> List(3, 4, 5) contains 6 res1: Boolean = false
更新:contains是在SeqLike中定义的,所以上面的代码适用于任何序列。更新2:以下是SeqLike中contains的定义:
contains
SeqLike
def contains(elem: Any): Boolean = exists (_ == elem)
wixjitnu3#
假设一个Set[A]也是一个A => Boolean,你可以说:
Set[A]
A => Boolean
Set(a, b, c, d, e) apply x
实际上,为这个定义一些pimpin' sugar是很好的:
class PredicateW[A](self : A => Boolean) { def ∈:(a : A) = self apply a } implicit def pred2wrapper[A](p : A => Boolean) = new PredicateW(p)
然后你可以这样写代码:
x ∈: Set(a, b, c, d, e)
6mzjoqzu4#
通过综合所有其他答案,我得出了“正确”答案:
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
再见
gudnpqoy5#
存在:
List (3, 4, 5).exists (_ == 4) // res20: Boolean = true
查找和筛选接近:
List (3, 4, 5).find (_ == 4) // res16: Option[Int] = Some(4) List (3, 4, 5).filter (_ == 4) // res17: List[Int] = List(4)
我的第一个答案是,和其他答案一样,使用包含:
List (3, 4, 5).contains (4)
但后来我想,它只适用于像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)
我明白了,我必须更频繁地使用equals/eq/==,才能把区别记在脑子里。
这是最简单的答案。
myzjeezk6#
Set(a, b, c, d, e)(x)也可以工作。我将把原因留给读者作为练习。:—)
Set(a, b, c, d, e)(x)
wgeznvg77#
frebpwbc8#
也适用于Scala 3的解决方案:
implicit class PowerAny[A](a: A) { /** * 2 in (1,2,3,"foo") -> true * * 4 in (1,2,3,"foo") -> false */ def in(seq: A*): Boolean = seq.contains(a) }
(My更新其他解决方案之一的请求被拒绝。)
8条答案
按热度按时间iibxawm41#
您可以按如下方式实现
in
运算符:wnvonmuf2#
我更喜欢
contains(a)
而不是exists(_ == a)
:更新:
contains
是在SeqLike
中定义的,所以上面的代码适用于任何序列。更新2:以下是
SeqLike
中contains
的定义:wixjitnu3#
假设一个
Set[A]
也是一个A => Boolean
,你可以说:实际上,为这个定义一些pimpin' sugar是很好的:
然后你可以这样写代码:
6mzjoqzu4#
通过综合所有其他答案,我得出了“正确”答案:
再见
gudnpqoy5#
存在:
查找和筛选接近:
我的第一个答案是,和其他答案一样,使用包含:
但后来我想,它只适用于像4这样的盒装值,而不适用于区分身份和平等的类。为了证明这一点,我写了一个小类,证明我错了::)
我明白了,我必须更频繁地使用equals/eq/==,才能把区别记在脑子里。
这是最简单的答案。
myzjeezk6#
Set(a, b, c, d, e)(x)
也可以工作。我将把原因留给读者作为练习。:—)wgeznvg77#
frebpwbc8#
也适用于Scala 3的解决方案:
(My更新其他解决方案之一的请求被拒绝。)