स्कैला में विलोम का सबसे अच्छा तरीका क्या है?


137

स्कैला में एक व्युत्क्रम प्रकार करने का सबसे अच्छा तरीका क्या है? मुझे लगता है कि निम्नलिखित कुछ धीमा है।

list.sortBy(_.size).reverse

क्या सॉर्टबाय का उपयोग करने का एक उचित तरीका है लेकिन रिवर्स प्रकार प्राप्त करना है? मैं बल्कि उपयोग करने की आवश्यकता नहीं होगी sortWith


1
नीचे दिए गए समाधान बहुत अच्छे हैं, लेकिन मैं अभी भी पढ़ने के लिए इस सरल तरीके को करने का आपका मूल तरीका ढूंढता हूं। मैंने सत्यापित किया है कि आपके द्वारा संदेह किए जाने पर इस तरह से लिखने के लिए एक कम्प्यूटेशनल खामी है। मैंने जो परीक्षण किया वह इस प्रकार है: वैल क्लॉक = नया टाइमर (1 से 1e6.toInt) .sorted (ऑर्डरिंग [int] .reverse) क्लॉक ।addLap ("सही तरीका") (1 से 1e6 .toInt)। sv.erse clock.addLap ("गलत तरीका") Println (clock.toString) [सही तरीका, lap = 76, dur। = 76] | [गलत तरीका, गोद = 326, डूर। = 250]
खोआ

जवाबों:


242

यदि आप कुछ सांख्यिक मान से सॉर्ट करते हैं, तो संकेत को बदलने का स्पष्ट तरीका हो सकता है

list.sortBy(- _.size)

अधिक आम तौर पर, छँटाई विधि द्वारा किया जा सकता है एक अंतर्निहित आदेश के साथ क्रमबद्ध किया जाता है, जिसे आप स्पष्ट कर सकते हैं, और आदेश में एक रिवर्स होता है (नीचे दी गई सूची रिवर्स नहीं) आप कर सकते हैं

list.sorted(theOrdering.reverse)

यदि आप जिस ऑर्डर को रिवर्स करना चाहते हैं, वह निहित ऑर्डर है, तो आप इसे [ऑर्डरिंग [ए]] (ए प्रकार जिसे आप ऑर्डर कर रहे हैं) या बेहतर ऑर्डरिंग [ए] द्वारा प्राप्त कर सकते हैं। यह होगा

list.sorted(Ordering[TheType].reverse)

SortBy ऑर्डरिंग.बी का उपयोग करने जैसा है, इसलिए आप कर सकते हैं

list.sorted(Ordering.by(_.size).reverse)

शायद (माइनस की तुलना में) लिखने के लिए सबसे छोटा नहीं है, लेकिन इरादा स्पष्ट है

अपडेट करें

अंतिम पंक्ति काम नहीं करती है। स्वीकार करने के लिए _में Ordering.by(_.size), संकलक जरूरतों पर जो टाइप हम आदेश दे रहे हैं पता करने के लिए, यह टाइप कर सकते हैं इतना है कि _। ऐसा लगता है कि सूची के तत्व का प्रकार होगा, लेकिन यह ऐसा नहीं है, जैसा कि सॉर्ट किए गए हस्ताक्षर हैं def sorted[B >: A](ordering: Ordering[B])। आदेश हो सकता है A, लेकिन A(आप उपयोग कर सकते हैं byHashCode : Ordering[Any] = Ordering.by(_.hashCode)) के किसी पूर्वज पर भी हो सकता है । और वास्तव में, तथ्य यह है कि सूची सहसंयोजक है इस हस्ताक्षर को बल देता है। एक कर सकते हैं

list.sorted(Ordering.by((_: TheType).size).reverse)

लेकिन यह बहुत कम सुखद है।


सुपर उपयोगी - मुझे यकीन नहीं था कि मैं एक गूंगा सवाल पूछ रहा हूं, लेकिन मैंने आपके जवाब से बहुत कुछ सीखा है!
schmmd

सिवाय इसके कि यह काम नहीं करता है। मुझे कभी जवाब नहीं देना चाहिए जब मेरे पास कोई आरपीएल काम नहीं है। अपडेट देखें
डिडियर ड्यूपॉन्ट

और एक माध्यमिक क्षेत्र पर छंटनी करने के लिए, एक टपल लौटें:list.sortBy(x => (-x.size, x.forTiesUseThisField))
ब्रेंट फॉस्ट

2
इसके बजाय list.sorted(Ordering.by((_: TheType).size).reverse)विचार करना list.sorted(Ordering.by[TheType, Int](_.size).reverse)यह स्पष्ट है (लेकिन लंबे समय तक) veiw के मेरी बात के लिए।
चेरी

5
मैं व्यक्तिगत रूप से list.sortBy(_.size)(Ordering[Int].reverse)भी पसंद करता हूं ।
dtech


27

शायद इसे थोड़ा और छोटा करें:

def Desc[T : Ordering] = implicitly[Ordering[T]].reverse

List("1","22","4444","333").sortBy( _.size )(Desc)

19

आसान मटर (कम से कम मामले में size):

scala> val list = List("abc","a","abcde")
list: List[java.lang.String] = List(abc, a, abcde)

scala> list.sortBy(-_.size)
res0: List[java.lang.String] = List(abcde, abc, a)

scala> list.sortBy(_.size)
res1: List[java.lang.String] = List(a, abc, abcde)

9

sortByअंतर्निहित पैरामीटर है ordजो आदेश प्रदान करता है

def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]

इसलिए, हम स्वयं की Orderingवस्तु को परिभाषित कर सकते हैं

scala> implicit object Comp extends Ordering[Int] {
 | override def compare (x: Int, y: Int): Int = y - x
 | }
defined module Comp

List(3,2,5,1,6).sortBy(x => x)
res5: List[Int] = List(6, 5, 3, 2, 1)

9

दोनों sortWithऔर sortByएक कॉम्पैक्ट वाक्य रचना है:

case class Foo(time:Long, str:String)

val l = List(Foo(1, "hi"), Foo(2, "a"), Foo(3, "X"))

l.sortWith(_.time > _.time)  // List(Foo(3,X), Foo(2,a), Foo(1,hi))

l.sortBy(- _.time)           // List(Foo(3,X), Foo(2,a), Foo(1,hi))

l.sortBy(_.time)             // List(Foo(1,hi), Foo(2,a), Foo(3,X))

मुझे sortWithसमझने में आसानी होती है।



1

उन मामलों में एक और संभावना जहां आप एक फ़ंक्शन पास करते हैं जो आप उदाहरण के लिए सॉर्ट के माध्यम से सीधे एक ऐरेबफ़र में संशोधित करने में सक्षम नहीं हो सकते हैं:

val buf = collection.mutable.ArrayBuffer[Int]()
buf += 3
buf += 9
buf += 1

// the sort function (may be passed through from elsewhere)
def sortFn = (A:Int, B:Int) => { A < B }

// the two ways to sort below
buf.sortWith(sortFn)                        // 1, 3, 9
buf.sortWith((A,B) => { ! sortFn(A,B) })    // 9, 3, 1

0

यह मेरा कोड है;)

val wordCounts = logData.flatMap(line => line.split(" "))
                        .map(word => (word, 1))
                        .reduceByKey((a, b) => a + b)

wordCounts.sortBy(- _._2).collect()

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