【问题标题】:Scala equivalent of Python's "in" operator for sets?Scala 相当于 Python 的“in”操作符的集合?
【发布时间】:2014-10-03 20:04:21
【问题描述】:

在 Scala 中,可以使用“包含”检查项目是否是 Set 的成员:

object Main extends App {
    val the_set = Set(1, 2, 3, 4)
    if( the_set contains 3 ) println("The set contains 3!")
}

但是,我想做一个类似的比较,但首先是物品,最后是套装(我知道这是一个小风格点)。我有一些 Python 的背景,所以我希望有一些类似于 Python 的 in 运算符的东西:

the_set = set([1, 2, 3, 4])
if 3 in the_set: print "The set contains 3!"

在 Scala 中有没有办法做到这一点?如果你很好奇,我想这样做的原因是编写一个简洁的 if 语句,将值与我构建的长 Set 进行比较。同时,我希望item排在第一位,这样代码更容易阅读和理解。

谢谢!

【问题讨论】:

  • the_set contains 3 看起来已经很简洁了。我看不出3 in the_set 更容易阅读。
  • @Gangstead in 对于大型内联集看起来更好(但是,简单的解决方案是诉诸变量定义)。
  • @Gangstead:我同意变量定义会起作用。出于文体原因,我只是希望有更好的东西。 (是的,我很肤浅)

标签: scala scala-collections


【解决方案1】:

这是一个如何做到这一点的示例:

scala> implicit class InOperation[T](v: T) extends AnyVal { def in(s: Set[T]) = { s contains v } }
defined class InOperation

scala> val x = Set(1,2,3)
x: scala.collection.immutable.Set[Int] = Set(1, 2, 3)

scala> 2 in x
res0: Boolean = true

它使用implicit classin 方法(采用Set[T])添加到任意类型T 并检查对象是否在集合中。

【讨论】:

  • 不幸的是,它在 ScalaTest FlatSpec 中变得模棱两可,可以通过约束 T 或更聪明的方法来修复。
  • 使用Value Classes 消除运行时开销。
  • 优秀的答案!实际上,我之前实际上使用过隐式类来对 Scala 的各个部分进行一些其他小的更改。尽管如此,我还是觉得像“in”运算符这样的东西应该作为标准库的一部分内置。你认为他们会接受补丁吗?
  • @bnsmith 可能是,但我不这么认为。像这样的东西在你的 DSL 中是一件好事,Scala 允许你在需要时实现它,但是 Scala 的标准库已经建立了这样做的方法,我不太确定用另一种方法污染库是一个好方法想法(另外,我记得标准的 lib 维护者抱怨需要在某些会议上减少几乎相同的方法的数量)。不过,这是有争议的。
  • @bnsmith 2 in xx contains 2 都是可读的,所以这是个人风格。 Scala 采用后者,因为它更适合其他功能。恕我直言,当它与其他功能结合使用时,它也变得更具可读性,例如:if (List(1,2,3) map (_ * 2) filter (_ > 2) contains 4)
【解决方案2】:

Scala Set 有方法contains。所以,你可以这样使用它:

val x = Set(1,2,3)
x.contains(1) // True

你也可以使用语法糖,这样称呼它:

x(1) // True

【讨论】:

  • 那不是语法糖,那是apply() 方法。 ScalaDocs page 声明“此方法等同于包含”。并且 OP 对 contains() 方法了如指掌,正如这个 5 年老问题的顶部所明确提到的那样。
猜你喜欢
  • 2019-05-01
  • 2011-06-27
  • 2015-05-17
  • 1970-01-01
  • 1970-01-01
  • 2021-11-18
  • 1970-01-01
  • 1970-01-01
  • 2021-02-12
相关资源
最近更新 更多