2012-06-19 10 views
13

एक ही धर्मार्थ के दो tuples दिया, मैं lexicographically उनकी तुलना कैसे कर सकते हैं? ऐसा लगता है कि यह निम्न स्निपेट में जितना सरल होना चाहिए, लेकिन ऐसा नहीं है। इसे कैसे करना है इसका कोई आसान उदाहरण?स्कैला ट्यूपल्स की व्याख्यात्मक रूप से तुलना कैसे करें?

var x = (1,2,3) < (1,2,4) 

थे वे सूचीबद्ध करता है, मैं एक पुनरावर्ती समारोह है कि जब तक एक अंतर या एक सूची के अंत मिला था सूचियों 'सिर तुलना हैं निर्धारित कर सकते हैं, लेकिन मुझे नहीं लगता मैं कर सकता है कि tuples के लिए है।

उत्तर

22

यह है, क्योंकि जबकि

var x = (1,2,3) < (1,2) 

बहुत सरल लग रहा है सरल नहीं है

var x = (1,false,3) < (1,2) 

नहीं है। आप गैर-आदेशित प्रकारों से कैसे निपटते हैं? आप एक ही टुपल स्थिति में विभिन्न प्रकारों से कैसे निपटते हैं?

क्या आप सभी प्रकारों को एक जैसा होना चाहते हैं? उस स्थिति में, आपके पास टुपल नहीं है। एक ट्यूपल का पूरा बिंदु यह है कि इसकी धैर्य तय होती है (आप स्थिर रूप से जानते हैं कि यह कितना बड़ा है) और प्रत्येक तत्व एक अलग प्रकार का हो सकता है।

यदि मुझे खुद को उस समस्या के साथ मिला - और मैं बहुत कठिन प्रयास नहीं करता - मैं बेकार पकड़ लेता हूं, tuples को एचएलिस्ट की तरह कुछ में परिवर्तित करता हूं, और फिर उस पर तुलना करने की कोशिश करता हूं।

संपादित

आह, अब यह बहुत आसान है:

import scala.math.Ordering.Implicits._ 
var x = (1,2,3) < (1,2,4) 

ये अतिरिक्त implicits स्वचालित रूप से उपलब्ध है, क्योंकि वे कुछ परिस्थितियों में implicits अपसारी में परिणाम कर सकते नहीं हैं।

+0

अच्छे अंक, डैनियल। मैंने अपने प्रश्न को राज्य में संपादित किया है तुलना की तुलना में हमेशा एक ही धैर्य है। गैर-आदेशित प्रकारों के लिए, मेरे tuples में प्रतीकों होना चाहिए (यही कारण है कि मैं सूचियों के बजाय tuples के लिए गया था), लेकिन क्योंकि मुझे प्रतीकों का ऑर्डर करने का कोई तरीका नहीं मिला है, इसलिए, मैं संख्याओं का उपयोग करूंगा। क्या मुझे सूचियों का उपयोग करना चाहिए? अगर मुझे सूची में प्रतीकों को जोड़ने की ज़रूरत है तो क्या होगा? – lasaro

+1

@lasaro ठीक है, अब आप समस्या को सरल बनाते हैं, एक अपेक्षाकृत आसान समाधान है। संपादित उत्तर देखें। –

+0

धन्यवाद डैनियल, आपके लिए बहुत संक्षिप्त उदाहरण है। – lasaro

2

सबसे आसान तरीका उन पर एक अंतर्निहित आदेश [टी] को परिभाषित करना है, लेकिन फिर आपको इस क्रम को सॉर्ट फ़ंक्शन (या किसी अन्य फ़ंक्शन से तुलना करना चाहता है) को पास करना होगा। इसे पूरी तरह से पारित करना भी संभव है।

एक और तरीका होगा, एक अंतर्निहित कलाकारों के माध्यम से < ऑपरेटर द्वारा टपल वर्ग का विस्तार करने के:

implicit def compareTuple[T](lhs: (T,T)) = new { 
    def <(rhs: (T,T)) = lhs._1<rhs._1 || (lhs._1==rhs._1 && lhs._2<rhs._2) 
} 

संपादित करें: आप अन्य तुलना ऑपरेटरों भी करना चाहते हैं, तो आप उन्हें मिल सकता है आदेश दिया से [टी] इनहेरिट द्वारा:

implicit def compareTuple[T](lhs: (T,T)) = new Ordered[(T,T)] { 
    def compare(rhs: (T,T)) = ... 
} 

EDIT2: आप भी tuples की तुलना करने की जरूरत है विभिन्न आकारों में, आप उत्पाद इटरेटर फ़ंक्शन का उपयोग कर सकते हैं जिसे सभी ट्यूपल क्लासेस (see documentation) में परिभाषित किया गया है और आपको ट्यूपल पर एक इटरेटर प्राप्त करने की अनुमति देता है। इस तरह आप एक समारोह लिख सकते हैं जैसे आप इसे एक सूची के साथ करेंगे।

edit3: कुछ यह होगा की तरह:

implicit def compareTuple[T <: Product](lhs: T) = new Ordered[T] { 
    def compare[U <: Product](rhs: U) = { 
     def compare(lhs: Any, rhs: Any) = ... 
     def iteratorCompare(lhs: Iterator[Any], rhs: Iterator[Any]):Int = 
      if(!lhs.hasNext) 
       if(!rhs.hasNext) 
        0 
       else 
        -1 
      else if(!rhs.hasNext) 
       1 
      else 
       compare(lhs.next,rhs.next) 
     iteratorCompare(lhs.productIterator,rhs.productIterator) 
    } 
} 

लेकिन इस दृष्टिकोण आप प्रकार के बारे में देखभाल करने के लिए है के साथ। क्योंकि फ़ंक्शन ट्यूपल तत्वों के प्रकारों को नहीं जानता है (वे एक ही टुपल के अंदर अलग हो सकते हैं), यह केवल आपको एक इटरेटर [कोई भी] प्रदान कर सकता है। तो आपको अपनी इच्छित चीज़ों को संभालने के लिए तुलना (कोई भी, कोई भी) फ़ंक्शन परिभाषित करना होगा।

+1

आप संभवतः '-Xexperimental' सक्षम कर सकते हैं जो 'Any' के बजाय LUB का चयन करेगा। आपके पूरे उत्तर के लिए – soc

+0

धन्यवाद हेनज़ी। मैंने इससे बहुत कुछ सीखा, लेकिन मेरे प्रश्न और स्केल कौशल के स्तर के लिए, डैनियल इस बिंदु पर अधिक था। – lasaro

9

यदि आप < का उपयोग करना चाहते हैं तो डैनियल का समाधान काम करता है लेकिन यदि आपको compare विधि की आवश्यकता है तो आप निम्न (उदाहरण के लिए) कर सकते हैं।

implicitly[Ordering[Tuple2[Int, Int]]].compare((1,2), (2,3)) 

तुलनीय भागों के साथ सभी tuples के लिए आदेश निर्धारित हैं।

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