在Scala中,有没有一种简洁明了的方法来比较一个值与多个值

发布于 2024-11-05 18:13:04 字数 249 浏览 2 评论 0原文

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

在 SQL 查询中,相同的概念可以通过

WHERE x IN (a, b, c, d, e).

Scala 中是否有类似的东西来处理,就这么简单?我知道可以使用复杂的表达式在一行中完成此操作,例如构建 HashSet 并检查集合中是否存在,但我更愿意使用简单的构造(如果可用)。

Say I have a variable x, and I want to check if it's equal to any one of multiple values a, b, c, d, e (I mean the == equality, not identity).

In an SQL query the same concept is handled with

WHERE x IN (a, b, c, d, e).

Is there something equivalent in Scala that's as straightforward as that? I know it's otherwise possible to do it in one line with a complex expression such as building a HashSet and checking for existence in the set, but I'd prefer to use a simple construct if it's available.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

忘你却要生生世世 2024-11-12 18:13:04

您可以按如下方式实现 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

You could implement an in operator as follows:

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
明媚如初 2024-11-12 18:13:04

我更喜欢 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中:

def contains(elem: Any): Boolean = exists (_ == elem)

I would prefer contains(a) over exists(_ == a):

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

scala> List(3, 4, 5) contains 6
res1: Boolean = false

Update: contains is defined in SeqLike, so the above works with any sequence.

Update 2: Here is the definition of contains in SeqLike:

def contains(elem: Any): Boolean = exists (_ == elem)
聽兲甴掵 2024-11-12 18:13:04

假设 Set[A] 也是 A => Boolean,你可以说:

Set(a, b, c, d, e) apply x

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

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)

Given that a Set[A] is also a A => Boolean, you can just say:

Set(a, b, c, d, e) apply x

It's actually quite nice to define some pimpin' sugar for this:

class PredicateW[A](self : A => Boolean) {
  def ∈:(a : A) = self apply a
}
implicit def pred2wrapper[A](p : A => Boolean) = new PredicateW(p)

Then you can write the code like so:

x ∈: Set(a, b, c, d, e)
伤感在游骋 2024-11-12 18:13:04

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

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

Ta-da。

By synthesizing all the other answers, I have come up with the correct answer:

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

Ta-da.

落花浅忆 2024-11-12 18:13:04

存在:

 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)

与其他答案一样,我的第一个答案是使用 contains:

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/== ,才能将这些区别带入我的大脑。

List (3, 4, 5).contains (4)

恕我直言,答案是最简单的。

exists:

 List (3, 4, 5).exists (_ == 4)
 // res20: Boolean = true

find and filter come close:

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

My first answer was, as other answers, to use contain:

List (3, 4, 5).contains (4)

but then I thought, it would only work for boxed values like 4, not for classes, which distinguish identity and equality. To prove it, I wrote a small class, which proved me wrong: :)

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) 

I see, I have to use equals/eq/== more often, to get the distinctions into my brain.

List (3, 4, 5).contains (4)

is imho the answer which is most easy.

萌酱 2024-11-12 18:13:04

Set(a, b, c, d, e)(x) 也有效。我将把这样做的原因留给读者作为练习。 :-)

Set(a, b, c, d, e)(x) works as well. I'll leave the reasons for it as an exercise to the reader. :-)

So尛奶瓶 2024-11-12 18:13:04
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)
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)
酒浓于脸红 2024-11-12 18:13:04

也适用于 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)
}

我更新其他解决方案之一的请求被拒绝。)

Solution which also works with 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 request to update one of the other solutions was rejected.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文