2013-04-17 10 views
14

पैटर्न पैटर्न मिलान सूचियां एक पैटर्न को निर्दिष्ट करने का कोई तरीका है जो आकार के साथ अधिक से अधिक (या कम) या स्कैला में एक निश्चित मान के बराबर है?कुछ आकार या अधिक/कम

उदाहरण के लिए, मैं आकार 3 या उससे कम की सभी सूचियों पर समान कार्रवाई लागू करना चाहते हैं:

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

वहाँ दो मामलों को यह कम करने के लिए कोई तरीका है?

+0

मुझे लगता है कि यह एक गार्ड के साथ किया जा सकता है ... मामला ... अगर (tail.size> = x) => – Dan

उत्तर

11

हाँ, यद्यपि आप मामलों के क्रम को उल्टा करना होगा:

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

ध्यान दें कि मैं बजाय list की चर्चा करते हुए के पैटर्न में सूची में एक नया चर l बाध्य किया है, और है कि जब मैंने एक चर की आवश्यकता नहीं है तो मैंने _ का उपयोग किया है। मैं इन दोनों प्रथाओं में चिपके रहने का सुझाव दूंगा, लेकिन जवाब उनके बिना बिल्कुल वही काम करेगा।

+1

मैं इस तरह के एक सुलझा सिंटेक्स के उपयोग की बात नहीं दिख रहा है जब गार्ड हालत क्या सवाल इस सवाल में पूछा गया है। –

+1

@ डेनिसआर .: सबसे पहले, मैं पूछे गए प्रश्न का उत्तर दे रहा था, और दूसरा, मुझे यकीन नहीं है कि जब आप सूचियों के साथ काम कर रहे हों, तो यह जवाब वास्तव में गार्ड की स्थिति से कम मूर्खतापूर्ण है, जहां 'लंबाई' एक महंगी ऑपरेशन है। यदि आप सूची (और आपको चाहिए) को पार करने से बचना चाहते हैं, तो आपको कुछ केस लिखना होगा जैसे 'एल एल लम्बाई कॉम्पैयर (3)> -1', जो कि अपने ही प्रकार का अजीब है। –

+1

आप जटिलता के बारे में सही हैं और लंबाई का उपयोग कर रहे हैं। मैं इस समाधान को पसंद करता हूं क्योंकि लंबाई स्पष्ट रूप से लिखी जाती है और कई "_" -1 के रूप में नहीं लिखी जाती है। आपकी व्याख्या के लिए धन्यवाद। –

6

यदि सादे पुराने के साथ गलत है तो/else ??

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

भी जटिलता O(len) है इस प्रकार भले ही सूची लंबी है, len कारक यह तय करना है:

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

क्या होगा यदि सूची वास्तव में लंबी है? लंबाई का उपयोग किए बिना मैच/केस बेहतर होगा ... – huynhjl

+5

अच्छा बिंदु। इस मामले में आप 'लंबाई कॉम्पैयर' का उपयोग कर सकते हैं। –

+0

मुझे यकीन नहीं है कि "वास्तव में लंबा" क्या हो सकता है, लेकिन 'सूची' के पास प्रति तत्व काफी आकार का ओवरहेड होता है और बहुत बड़े संग्रह के लिए दृढ़ता से संकेत नहीं दिया जाता है। वे वास्तव में केवल एक बड़ा गुण है: बहुत ही कुशल सिर/पूंछ अपघटन। –

4

तुम भी साथ कर सकते हैं।

ऊपर कॉल op अगर list.size < len बाकी other

10

कॉल आप एक पैटर्न मिलान का उपयोग पर जोर देते हैं, तो आप एक गार्ड हालत इसके लिए उपयोग कर सकते हैं (? हो सकता है आप अधिक मैच मामलों शामिल करना चाहते हैं):

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

लंबाई का उपयोग करना कॉम्पैयर सूची की लंबाई की तुलना करने के लिए अधिक कुशल होगा 3 –

संबंधित मुद्दे