2012-04-05 31 views
72

स्कैला में दो फ़ील्ड द्वारा सूची को सॉर्ट करने का तरीका, इस उदाहरण में मैं अंतिम नाम और प्रथम नाम से सॉर्ट करूंगा?स्कैला में दो फ़ील्ड द्वारा सूची कैसे क्रमबद्ध करें?

case class Row(var firstName: String, var lastName: String, var city: String) 

var rows = List(new Row("Oscar", "Wilde", "London"), 
       new Row("Otto", "Swift", "Berlin"), 
       new Row("Carl", "Swift", "Paris"), 
       new Row("Hans", "Swift", "Dublin"), 
       new Row("Hugo", "Swift", "Sligo")) 

rows.sortBy(_.lastName) 

मैं इस

rows.sortBy(_.lastName + _.firstName) 

जैसी चीजों की कोशिश, लेकिन यह काम नहीं करता। तो मैं एक अच्छे और आसान समाधान के लिए उत्सुक हो।

उत्तर

173
rows.sortBy(r => (r.lastName, r.firstName)) 
+4

क्या होगा यदि हम अंतिम नाम पर क्रमबद्ध करना चाहते हैं और फिर पहले नाम पर प्राकृतिक प्रकार चाहते हैं? –

+9

@SachinK: आपको 'पंक्ति' वर्ग के लिए अपना स्वयं का 'ऑर्डरिंग' बनाना होगा और इसे 'क्रमबद्ध' विधि के साथ उपयोग करना होगा: 'rows.sorted (customOrdering)'। आप 'tuple2' के लिए कस्टम 'ऑर्डरिंग' का भी उपयोग कर सकते हैं:' rows.sortBy (r => (r.lastName, r.firstName)) (ऑर्डरिंग .uple2 (ऑर्डरिंग। स्ट्रिंग.वर्स, ऑर्डरिंग। स्ट्रिंग)) ' । – senia

+4

@SachinK: आप 'customOrdering' को मैन्युअल रूप से 'ऑर्डरिंग [पंक्ति]' के रूप में लागू कर सकते हैं या इस तरह 'ऑर्डरिंग.बी'' का उपयोग कर सकते हैं:' val customOrdering = 'Ordering.by ((r: पंक्ति) => (r.lastName, r । फर्स्टनाम)) (ऑर्डरिंग .uple2 (ऑर्डरिंग। स्ट्रिंग.वर्स, ऑर्डरिंग। स्ट्रिंग)) ' – senia

9
rows.sortBy (row => row.lastName + row.firstName) 

आप अपने प्रश्न के रूप में, मर्ज किए गए नामों से सॉर्ट करने के लिए चाहते हैं, या

rows.sortBy (row => (row.lastName, row.firstName)) 

अगर आप पहले lastName द्वारा क्रमबद्ध करना चाहते हैं, तो firstName; लंबे नामों के लिए प्रासंगिक (जंगली, वाइल्डर, वाइल्डमैन)।

आप लिखते हैं

rows.sortBy(_.lastName + _.firstName) 
2 रेखांकन के साथ

हैं, तो विधि दो पैरामीटर उम्मीद:,

<console>:14: error: wrong number of parameters; expected = 1 
     rows.sortBy (_.lastName + _.firstName) 
          ^
+1

इसका क्रम शायद पहले नाम, फिर अंतिम नाम से सॉर्ट करने जैसा नहीं होगा। – Marcin

+1

विशेष रूप से, जब अंतिम नाम भिन्न लंबाई –

+0

@Marcin: lastName, तो firstName। हाँ तुम सही हो। –

5

सामान्य तौर पर आप एक स्थिर छँटाई एल्गोरिथ्म उपयोग करते हैं, आप कर सकते हैं बस प्रकार एक कुंजी के द्वारा, फिर अगला।

rows.sortBy(_.firstName).sortBy(_.lastName) 

अंतिम परिणाम अंतिम नाम से क्रमबद्ध किया जाएगा, फिर यह बराबर है, पहले नाम से।

+0

क्या आप वाकई स्केल 'sortBy' स्थिर प्रकार का उपयोग करते हैं? अन्यथा यह जवाब व्यर्थ है। –

+1

@ ओम-नाम-नाम: http://www.scala-lang.org/api/current/scala/util/Sorting$.html quickSort केवल मूल्य प्रकारों के लिए परिभाषित किया गया है, इसलिए हां। – Marcin

+1

'पंक्तियां' एक अपरिवर्तनीय सूची है और 'sortBy' यह बदलने के बजाए एक नया मान देता है जिस पर यह काम करता है (यहां तक ​​कि उत्परिवर्तनीय कक्षाओं में भी)। तो आपकी दूसरी अभिव्यक्ति सिर्फ मूल अनुरक्षित सूची को सॉर्ट कर रही है। –

-4

शायद यह केवल tuples की एक सूची के लिए काम करता है, लेकिन

scala> var zz = List((1, 0.1), (2, 0.5), (3, 0.6), (4, 0.3), (5, 0.1)) 
zz: List[(Int, Double)] = List((1,0.1), (2,0.5), (3,0.6), (4,0.3), (5,0.1)) 

scala> zz.sortBy(x => (-x._2, x._1)) 
res54: List[(Int, Double)] = List((3,0.6), (2,0.5), (4,0.3), (1,0.1), (5,0.1)) 

काम करते हैं और यह व्यक्त करने के लिए एक आसान तरीका प्रतीत होता है।

+0

लेकिन स्ट्रिंग्स के लिए काम नहीं करता है, जो ओपी सॉर्ट कर रहा है। –

+0

इस प्रश्न में पहले से ही कई अच्छी तरह से प्राप्त उत्तरों हैं जो tuples की सूचियों तक सीमित नहीं हैं। तो इसे पोस्ट करने का कारण क्या है? – honk

+0

@ होंक: पूर्व समाधान वास्तव में टुपल्स की सूची पर काम नहीं करते हैं (AFAICT)। अगर मैं स्कैला नौसिखिया नहीं था, तो शायद मैं समझूंगा कि उस मामले में काम करने के लिए उन पूर्व समाधानों को कैसे मोड़ना है, लेकिन आज मैं नहीं करता हूं। मैंने सोचा कि मेरा जवाब एक और स्कैला नौसिखिया को वही काम करने में मदद कर सकता है जो मैं करने की कोशिश कर रहा था। – spreinhardt

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