在Scala中,是否可以匹配一系列的值?
例如:
val t = 5
val m = t match {
0 until 10 => true
_ => false
}
如果
t
在0到10之间,m
将为 true
,否则为false。当然,这个小技巧不起作用,但有没有办法实现类似的功能?在Scala中,是否可以匹配一系列的值?
例如:
val t = 5
val m = t match {
0 until 10 => true
_ => false
}
t
在0到10之间,m
将为 true
,否则为false。当然,这个小技巧不起作用,但有没有办法实现类似的功能?使用Range
进行守卫:
val m = t match {
case x if 0 until 10 contains x => true
case _ => false
}
scala> 0.0 until 10.0 by 0.1 contains 4.0
,返回res0: Boolean = true
- Alexander Azarovval m = t match {
case x if (0 <= x && x < 10) => true
case _ => false
}
Range.contains
被覆盖了,所以它不需要扫描任何东西!这仍然是一些额外的代码,但 Hotspot 应该可以轻松地内联和优化它。 - Alexey Romanov根据这些定义:
trait Inspector[-C, -T] {
def contains(collection: C, value: T): Boolean
}
implicit def seqInspector[T, C <: SeqLike[Any, _]] = new Inspector[C, T]{
override def contains(collection: C, value: T): Boolean = collection.contains(value)
}
implicit def setInspector[T, C <: Set[T]] = new Inspector[C, T] {
override def contains(collection: C, value: T): Boolean = collection.contains(value)
}
implicit class MemberOps[T](t: T) {
def in[C](coll: C)(implicit inspector: Inspector[C, T]) =
inspector.contains(coll, t)
}
2 in List(1, 2, 4) // true
2 in List("foo", 2) // true
2 in Set("foo", 2) // true
2 in Set(1, 3) // false
2 in Set("foo", "foo") // does not compile
2 in List("foo", "foo") // false (contains on a list is not the same as contains on a set)
2 in (0 to 10) // true
因此,您需要的代码将是:
val m = x in (0 to 10)
以下是使用范围进行匹配的另一种方法:
val m = t match {
case x if ((0 to 10).contains(x)) => true
case _ => false
}
另一个选择是使用隐式将其添加到语言中,我为int和Range添加了两个变体。
object ComparisonExt {
implicit class IntComparisonOps(private val x : Int) extends AnyVal {
def between(range: Range) = x >= range.head && x < range.last
def between(from: Int, to: Int) = x >= from && x < to
}
}
object CallSite {
import ComparisonExt._
val t = 5
if (t between(0 until 10)) println("matched")
if (!(20 between(0 until 10))) println("not matched")
if (t between(0, 10)) println("matched")
if (!(20 between(0, 10))) println("not matched")
}
val m = 0 until 10 contains t
实际上是相同的,但更短。它将为您提供真/假答案。如果您只需要布尔答案。 - Peter Perháč