2013-09-03 45 views
7

Có thủ thuật Scala nào để bật tính năng khớp mẫu với các khóa bản đồ không? Nói cách khác, tôi muốn có một bộ giải nén bên cạnh bản đồ được chấp nhận cũng là một giá trị quan trọng có nghĩa là tôi muốn mẫu này chỉ khớp với nhau nếu giá trị phù hợp là một thể hiện của Bản đồ và có một mục nhập với khóa đã cho trong đó và giá trị cho mục nhập này phải tuân theo kiểu đối chiếu đệ quy.Kết hợp mẫu với Scala Các mục nhập bản đồ

Something như thế này:

myMap match { 
    case MyMap("a")(a) => // do smth with value a 
    case MyMap("b")(MyMap("c")(c)) => // do smth with value c 
} 

Cập nhật:

Tôi đã tìm thấy một số cách để tiếp cận gần hơn đến mục tiêu, nhưng nó vẫn không hoàn hảo bởi vì nó hàm ý nghĩa về tổng hợp giá trị khóa -holders:

case class MapKey[K](key: K) { 
    def unapply(o: Any) = o match { 
    case m: Map[K, _] ⇒ m.get(key) 
    case _ ⇒ None 
    } 
} 

val m1 = Map("a" → "aa", "b" → Map("c" → "cc")) 
val m2 = Map("a" → "aa", "d" → "dd") 

val b = MapKey("b") 
val c = MapKey("c") 
val d = MapKey("d") 

for (m ← List(m1, m2)) m match { 
    case b(c(x)) ⇒ println(s"b > c: $x") 
    case d(x) ⇒ println(s"d: $x") 
} 

tương tự câu hỏi: Can extractors be customized with parameters in the body of a case statement (or anywhere else that an extractor would be used)?

Yêu cầu tính năng: SI-5435

+1

Bạn có chắc chắn bạn cũng muốn để phù hợp với việc 'myMap' là Bản đồ? Còn gì nữa? – ziggystar

+0

Trường hợp thứ hai của bạn mong muốn đối sánh với điều gì? MyMap sẽ trông như thế nào nếu nó khớp với nhau? – Shadowlands

+0

Đây là một ví dụ đơn giản. Trên thực tế, tôi đang phát triển một thư viện Scala cho các hoạt động trên các loại Apple Cocoa có nguồn gốc từ NSObject. Đặc biệt, nhiệm vụ là phân tích cú pháp tệp iOS Plist rất phức tạp với nhiều cách khác nhau để mô tả cùng một điều. –

Trả lời

1

Có thể bạn đang tìm kiếm giải pháp mà bạn không thực sự cần? Không thể tưởng tượng những người vắt ở đây. Bạn có thể sử dụng PF nếu bạn muốn kết hợp cặp khóa-giá trị:

val map = Map[String, String]("a" -> "b") 

def matchTuple[A,B,C](map: Map[A,B])(pf: PartialFunction[(A,B), C]) = 
    map.collectFirst(pf) 

matchTuple(map) { 
    case ("a", b) => println("value for a is " + b) 
} 

loại Return phải là lựa chọn [Unit] vì chúng tôi sử dụng collectFirst và println

+0

Chuỗi một phần của hàm với vàThen và tùy chọn-ized qua .lift là cách tôi đã thực hiện thuật toán này cho đến nay. Tuy nhiên, tôi tò mò nếu nó có thể làm một cách ngắn gọn hơn. –

+1

Tôi nghĩ rằng đó là một nhiệm vụ toán học sai. Sử dụng kết hợp để tìm phần tử của bản đồ không có thứ tự có thể cho kết quả không được đoán trước –