2009-08-28 34 views
39

是否可以匹配Scala中的一系列值?一個範圍可以在Scala中匹配嗎?

例如:

val t = 5 
val m = t match { 
    0 until 10 => true 
    _ => false 
} 

m將是true如果t是0和10,但假之間否則。這一點當然不起作用,但有什麼辦法可以達到這樣的效果嗎?

+3

注意,通過寫 「0至10」 你的意思是0,1,2,。 ..,9(含0,不含10)。如果你想包含10,使用「0到10」。 – Jesper 2009-08-28 11:11:02

+0

看到一個相關的stackoverflow的問題:[我如何模式匹配在Scala範圍?](http://stackoverflow.com/questions/3160888/how-can-i-pattern-match-on-a-range-in -scala) – 2011-09-26 01:35:09

+0

標題詢問如何將'Range'類型的值與幾種可能性相匹配,例如「我有'(0..5)'還是'(1..6)'?」 – Raphael 2011-09-26 18:33:51

回答

65

衛隊使用Range

val m = t match { 
    case x if 0 until 10 contains x => true 
    case _ => false 
} 
+0

這很聰明!出於某種原因,我從來沒有想過這樣做... – 2009-08-28 14:12:24

27

您可以使用衛士:

val m = t match { 
    case x if (0 <= x && x < 10) => true 
    case _ => false 
} 
+0

就性能而言,此解決方案比@ alexander-azarov解決方案更好。有範圍需要被初始化,然後是範圍掃描。特別是對於大範圍,這可能成爲一個問題。 – Oosterman 2016-05-20 06:54:19

+1

'Range.contains'當然被覆蓋,所以它不需要掃描任何東西!它仍然有一些額外的代碼,但熱點應該內聯和優化它沒有問題。 – 2016-05-20 08:33:53

2

這裏有另一種使用範圍來匹配:

val m = t match { 
    case x if ((0 to 10).contains(x)) => true 
    case _ => false 
} 
+0

這複製@Alexander阿扎羅夫的答案。 – Glenn 2015-02-12 15:14:14

+0

t == 10的錯誤匹配。 – 2016-09-23 16:58:11

2

有了這些定義:

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) 
相關問題