दो क्षेत्रों द्वारा स्काला में सूची कैसे छाँटी जाए?


101

दो क्षेत्रों द्वारा स्काला में एक सूची को कैसे छाँटा जाए, इस उदाहरण में मैं अंतिम नाम और पहले नाम से छाँटूँगा?

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)

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

जवाबों:


216
rows.sortBy(r => (r.lastName, r.firstName))

4
क्या होगा अगर हम lastName पर पहले सॉर्ट करना चाहते हैं और फिर पहले नाम पर प्राकृतिक सॉर्ट करें?
सचिन के

14
@SachinK: आप अपने खुद के बनाने के लिए Orderingके लिए Rowवर्ग और साथ इसका इस्तेमाल sortedइस तरह विधि: rows.sorted(customOrdering)। आप कस्टम इस्तेमाल कर सकते हैं Orderingके लिए Tuple2इस तरह: rows.sortBy(r => (r.lastName, r.firstName))( Ordering.Tuple2(Ordering.String.reverse, Ordering.String) )
सेनिया

5
@SachinK: आप मैन्युअल customOrderingरूप Ordering[Row]से या Ordering.byइस तरह का उपयोग करके लागू कर सकते हैं : val customOrdering = Ordering.by (r (पंक्ति: पंक्ति) => (r.lastName, r.firstName)) (ऑर्डरिंग। Tup2 `
सेनिया

1
अति उत्कृष्ट। या अवरोही क्रम में छाँटने के लिएrows.sortBy(r => (-r.field1, -r.field2))
ब्रेंट फॉस्ट

@BrentFaust आप के -साथ उपयोग नहीं कर सकते String। आप का उपयोग करना चाहिए Ordering::reverseइस तरह से: rows.sortBy(r => (r.lastName, r.firstName))(implicitly[Ordering[(String, String)]].reverse)
सेनिया

12
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
इसका क्रम संभवत: Firstname द्वारा सॉर्ट करने के समान नहीं होगा, फिर lastname।
मार्सिन

1
विशेष रूप से, जब अंतिम नाम अलग-अलग लंबाई के होते हैं
लुइगी प्लिंज

7

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

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

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


क्या आप सुनिश्चित हैं कि स्कैला sortByस्थिर प्रकार का उपयोग करता है? अन्यथा यह उत्तर निरर्थक है।
om-nom-nom

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

1
rowsएक अपरिवर्तनीय सूची है और sortByउस पर काम करने के बजाय एक नया मूल्य लौटाता है, जिस पर वह काम करता है (यहां तक ​​कि उत्परिवर्तित कक्षाओं में भी)। तो आपकी दूसरी अभिव्यक्ति मूल अनसुलझी सूची को सुलझा रही है।
लुइगी प्लिंज

3
स्केल, सॉर्ट की हुड के तहत विधि विधि java.util.Arrays.sort का उपयोग करती है, जो ऑब्जेक्ट्स की सरणी के स्थिर होने की गारंटी देती है। तो, हाँ, यह समाधान सही है। (यह स्कला 2.10 में जाँच की गई थी)
मार्सिन पेइयुकीविज़िक

1
यह इस बनाम एक एकल छंटनी के प्रदर्शन के बारे में सोचने के लिए दिलचस्प है जो एक तुक बनाता है। इस दृष्टिकोण के साथ आपको स्पष्ट रूप से उन tuples को बनाने की आवश्यकता नहीं है, लेकिन tuple दृष्टिकोण के साथ आपको केवल पहले नामों की तुलना करनी होगी जहां अंतिम नामों का मिलान होता है। लेकिन मुझे लगता है कि इससे कोई फर्क नहीं पड़ता - यदि आप प्रदर्शन-महत्वपूर्ण कोड लिख रहे हैं तो आपको सॉर्ट का उपयोग नहीं करना चाहिए!
अमीगोनिको

-3

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

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

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


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

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

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

@ user3508605: मैं योगदान देने के लिए आपकी इच्छा की सराहना करता हूं। हालांकि, स्टैक ओवरफ्लो का विचार विशिष्ट समस्याओं के साथ सवाल करना है (जैसा कि यहां मामला है) और उन विशिष्ट समस्याओं (और केवल उन) को संबोधित करने वाले उत्तर हैं। आपका जवाब एक अलग समस्या का समाधान प्रदान करता है। इसलिए इसे पोस्ट करने के लिए यह गलत जगह है। यदि आपको लगता है कि आपका उत्तर मूल्यवान है, तो एक नया प्रश्न पूछें। नए प्रश्न में अपनी संबंधित समस्या का वर्णन करें और फिर अपना उत्तर दें। अंत में यहां अपना उत्तर निकालना न भूलें। आपके सहयोग के लिए धन्यवाद!
हार्न

@ हाँक: यकीन है, मैं अपना जवाब एक अलग सवाल पर ले जाऊँगा। और, यदि मैं इस प्रश्न के पिछले उत्तर में (मार्सिन से) टिप्पणी जोड़ने के लिए आप पर आरोप लगा सकता हूं, तो यह गलत प्रतीत होता है। (मेरे पास इस पर पोस्ट करने में सक्षम होने के लिए पर्याप्त विश्वसनीयता अंक नहीं हैं।) उस उत्तर में उदाहरण केवल एक कुंजी द्वारा पहले सॉर्ट करता है और फिर एक अलग कुंजी द्वारा फिर से सॉर्ट करता है, प्रभावी ढंग से पहले प्रकार के परिणामों को समाप्त करता है। कम से कम Tuples की सूची पर यह करता है।
वृहस्पति
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.