2009-08-28 10 views
39

Có thể kết hợp một loạt các giá trị trong Scala không?Phạm vi có thể phù hợp trong Scala không?

Ví dụ:

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

m sẽ true nếu t là giữa 0 và 10, nhưng sai khác. Điều này chút ít không làm việc tất nhiên, nhưng có cách nào để đạt được một cái gì đó như nó?

lính gác
+3

Lưu ý rằng bằng cách viết "0 đến 10" bạn có nghĩa là 0, 1, 2,. .., 9 (bao gồm 0, không bao gồm 10). Nếu bạn muốn bao gồm 10, sử dụng "0 đến 10". – Jesper

+0

Xem câu hỏi về lưu lượng truy cập stackoverflow có liên quan: [Làm cách nào để có thể khớp mẫu trên một phạm vi trong Scala?] (Http://stackoverflow.com/questions/3160888/how-can-i-pattern-match-on-a-range-in -scala) –

+0

Tiêu đề yêu cầu cách đối sánh giá trị loại 'Phạm vi' với một số khả năng, ví dụ: "Tôi có' (0..5) 'hay' (1..6) '?" – Raphael

Trả lời

65

Guard sử dụng Range:

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

Điều đó rất thông minh! Vì một lý do nào đó, tôi chưa bao giờ nghĩ đến việc làm theo cách đó ... –

27

Bạn có thể sử dụng:

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

Xét về hiệu suất, giải pháp này tốt hơn giải pháp @ alexander-azarov. Có phạm vi cần phải được khởi tạo, sau đó là quét phạm vi. Đặc biệt đối với các phạm vi rộng lớn, điều này có thể trở thành một vấn đề. – Oosterman

+1

'Range.contains' dĩ nhiên bị ghi đè nên không cần quét bất cứ thứ gì! Nó vẫn còn một chút mã bổ sung, nhưng Hotspot nên nội tuyến và tối ưu hóa nó mà không có vấn đề. –

2

Dưới đây là một cách khác để phù hợp với cách sử dụng một khoảng:

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

Câu trả lời này trùng lặp với câu trả lời của @Alexander Azarov. – Glenn

+0

Kết hợp sai cho t == 10. –

2

Với những định nghĩa:

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) 
    } 

Bạn có thể làm kiểm tra như thế này:

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 

Vì vậy, các mã bạn cần sẽ là:

val m = x in (0 to 10)