2013-04-17 17 views
14

Czy istnieje sposób określenia wzorca dopasowującego listę o wielkości większej (lub mniejszej) lub równej określonej wartości w Scali?Listy dopasowywania wzorów o określonym rozmiarze lub większym/mniejszym

Na przykład, jeśli chcesz zastosować tę samą akcję do wszystkich list o rozmiarze 3 lub mniej:

list match { 
    case Nil => op(list) 
    case x :: Nil => op(list) 
    case x :: y :: Nil => op(list) 
    case x :: y :: z :: Nil => op(list) 
    case x :: tail => other(list) 
} 

Czy istnieje sposób, aby zmniejszyć to do dwóch przypadkach?

+0

myślę, można to zrobić z osłoną ... przypadek ... if (tail.size> = x) => – Dan

Odpowiedz

11

Tak, chociaż trzeba odwrócić kolejność postępowania:

list match { 
    case l @ (_ :: _ :: _ :: _) => other(l) 
    case l => op(l) 
} 

Zauważ, że mam związane nowa zmienna l do listy w strukturze zamiast odniesienia do list, i że Użyłem _, gdy nie potrzebuję zmiennej. Sugerowałbym trzymanie się obu tych praktyk, ale odpowiedź bez nich byłaby dokładnie taka sama.

+1

ja nie widzę sensu używania takiej składni pogmatwanego gdy warunek guard wykonuje zadanie w pytaniu. –

+1

@DisisR .: Najpierw odpowiadałem na pytanie zadane, a po drugie, nie jestem pewien, czy ta odpowiedź jest w rzeczywistości mniej idiomatyczna niż warunek straży, gdy pracujesz z listami, gdzie "długość" jest kosztowną operacją. Jeśli chcesz uniknąć przechodzenia przez listę (i powinieneś), musisz napisać coś w stylu 'case l if l.lengthCompare (3)> -1', co jest rodzajem niezręczności. –

+1

masz rację co do złożoności i korzystania z lengthCompare. Preferuję to rozwiązanie, ponieważ jego długość jest wyraźnie napisana i nie jest zapisana jako liczba "_" -1. Dzięki za wyjaśnienie. –

6

Co jest nie tak z zwykłym starym, czy/else ??

if (list.length >= minimumLength) 
    longer(list) 
else 
    shorter(list) 
+1

Co, jeśli lista jest naprawdę długa? Mecz/skrzynka bez użycia długości byłaby lepsza ... – huynhjl

+5

Dobra uwaga. W tym przypadku możesz użyć 'lengthCompare'. –

+0

Nie jestem pewien, co może być "naprawdę długie", ale "Listy" mają znaczny narzut na jeden element i nie są wskazane dla bardzo dużych kolekcji. Mają tylko jedną wielką zaletę: bardzo wydajny rozkład głowy/ogona. –

4

Można również zrobić to z:

list.splitAt(len) match { 
    case (xs, Nil) => other(xs) 
    case (_, _) => op(list) 
} 

także złożoność jest O(len) więc nawet jeśli lista jeżeli długo, len jest czynnikiem decydującym.

Powyższe połączenia op jeśli list.size < len inny nazywa other

10

Jeśli upierasz się przy użyciu dopasowania wzoru (może chcesz dołączyć więcej przypadki meczu?), Można użyć warunku straży do niego:

list match { 
    case l if(l.size <= 3) => op(l) 
    case l => other(l) 
} 
+2

Korzystanie z lengthCompare byłoby bardziej efektywne przy porównywaniu długości listy do 3 –

Powiązane problemy