2013-04-17 6 views
14

Scala'da daha büyük (veya daha az) veya belirli bir değere sahip bir Listeyle eşleşen bir desen belirtmenin bir yolu var mı? ÖrneğinBelirli boyutta veya daha büyük/az desen eşleştirme listeleri

, ben büyüklük 3 veya daha az tüm listelere aynı işlemi uygulamak istiyorsanız:

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

iki durumda bu azaltmak için bir yolu var mı?

+0

i ... bu bir bekçi ile yapılabilir ... dava düşünüyorum (tail.size> = x) => – Dan

cevap

11

Evet, vakaların sırasını tersine çevirmek gerekir rağmen:

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

Not yerine list atıfta desen listesine yeni değişken l bağlı ettik ve bu Değişkene ihtiyacım olmadığında _ kullanmıştım. Bu uygulamaların her ikisine de yapışmayı öneriyorum, ama cevap onlarsız olarak aynı şekilde çalışacaktı.

+1

böylesine karartılmış sözdizimi kullanarak noktasını görmüyorum zaman bekçi koşulu ise iş soruda sordu. –

+1

@DenisR .: İlk olarak, soruyu şu şekilde sordum: İkinci olarak, bu yanıtın, liste ile çalışırken, 'length'un pahalı bir işlem olduğu durumda, gardiyan durumundan aslında daha az deyimsel olduğundan emin değilim. Eğer listeyi geçmekten kaçınmak istiyorsanız (ve yapmalısınız), eğer l.lengthCompare (3)> -1' ise kendi türünde garip olan bir şey yazmalısınız. –

+1

karmaşıklık ve uzunluk kullanımı hakkında haklısınız. Bu çözümü tercih ediyorum çünkü uzunluk açıkça yazılmış ve "_" -1 sayısı olarak yazılmamıştır. Açıklamanız için teşekkürler. –

6

Düz bir eskide neyin var/else ??

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

Ayrıca karmaşıklık liste uzun eğer len belirleyici unsur olduğu böylece bile O(len) geçerli:

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

Liste gerçekten uzunsa ne olur? Uzunluğu kullanmadan maç/dava daha iyi olurdu ... – huynhjl

+5

İyi nokta. Bu durumda 'lengthCompare' kullanabilirsiniz. –

+0

"Gerçekten uzun" olabileceğinden emin değilim, ancak "Listeler" tutulan öğenin başına büyük boyutlu ek yüke sahip ve çok büyük koleksiyonlar için güçlü bir şekilde gösterilmiyor. Gerçekten sadece tek bir büyük erdemleri var: çok etkili baş/kuyruk ayrıştırma. –

4

Ayrıca ile yapabilirsiniz. Eğer bir desen maçı kullanmakta ısrar ederse list.size < len başka other

10

çağırır

yukarıdaki aramalar op eğer, bunun için bir bekçi koşulunu kullanabilir (? belki daha maç vakaları dahil etmek istiyorum):

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

lengthCompare, liste uzunluğunu 3 ile karşılaştırmak için daha verimli olurdu –