2013-09-03 13 views
7

Czy istnieje jakaś sztuczka Scala, która umożliwia dopasowanie wzorców do klawiszy mapy? Innymi słowy, chciałbym mieć ekstraktor, który obok instancji Map zaakceptowałby także wartość klucza, co oznaczałoby, że chcę, aby ten wzorzec pasował tylko wtedy, gdy dająca się dopasować wartość jest instancją mapy i jest wpis z podanym kluczem w nim, a wartość tego wpisu podlega rekursywnemu dopasowaniu do wzorca.Dopasowanie wzorców do elementów mapy Scala

coś takiego:

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

Aktualizacja:

Znalazłem jakiś sposób, aby zbliżać się do celu, ale wciąż nie jest idealny, ponieważ implikuje definicję syntetycznego klucz-wartość -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") 
} 

podobne pytanie: Can extractors be customized with parameters in the body of a case statement (or anywhere else that an extractor would be used)?

Prośba o funkcję: SI-5435

+1

Czy na pewno chcesz także dopasować czy 'myMap' jest Mapa? Cóż innego mogło być? – ziggystar

+0

Jaki jest twój drugi przypadek, w którym spodziewasz się przeciwstawić? Jak wyglądałaby moja mapa, gdyby była dopasowana? – Shadowlands

+0

To jest uproszczony przykład. Właściwie pracuję nad biblioteką Scala dla operacji na typach Apple Cocoa pochodzących z NSObject. W szczególności zadaniem jest przeanalizowanie pliku Pli systemu iOS, który jest bardzo wyrafinowany z wieloma alternatywnymi sposobami opisywania tego samego. –

Odpowiedz

1

Może szukasz rozwiązania, którego naprawdę nie potrzebujesz? Nie wyobrażam sobie ekstraktorów tutaj. Można użyć PF jeśli chcesz dopasować par klucz-wartość:

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

Zwraca typ jest opcja [jednostka] ponieważ używamy collectFirst i println

+0

Funkcja PartialFunction jest przykuta, a następnie i opcjonalnie przez .lift jest sposób, w jaki dotychczas wdrożyłem ten algorytm. Jednak jestem ciekawy, czy można to zrobić w bardziej zwięzły sposób. –

+1

Myślę, że to matematycznie złe zadanie. Używanie dopasowania do znajdowania elementu nieuporządkowanej mapy może dać nieprzewidziane wyniki –

Powiązane problemy