मैं स्केल में एक सरणी को कैसे सॉर्ट करूं?


81

मैं देख सकता हूँ कि वहाँ एक छँटाई वस्तु है, Sortingएक quicksort विधि के साथ quickSort, उस पर।

मनमाने प्रकार की वस्तु की एक सरणी को छांटकर, इसका उपयोग करने का एक कोड उदाहरण क्या होगा? ऐसा लगता है कि मुझे Orderableविशेषता के कार्यान्वयन में पारित करने की आवश्यकता है , लेकिन मैं वाक्य रचना के बारे में अनिश्चित हूं।

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

जवाबों:


32

Sorting.quickSort संख्याओं या स्ट्रिंग्स का एक सरणी लेने के लिए फ़ंक्शंस की घोषणा करता है, लेकिन मैं मान रहा हूं कि आप अपनी कक्षाओं की वस्तुओं की एक सूची को सॉर्ट करना चाहते हैं?

फ़ंक्शन मुझे लगता है कि आप देख रहे हैं

quickSort [K](a : Array[K])(implicit view$1 : (K) => Ordered[K]) : Unit

जो, अगर मैं इस अधिकार को पढ़ रहा हूं, तो इसका मतलब है कि ऐरे में वस्तुओं का Orderedगुण होना चाहिए । इसलिए आपकी कक्षा का विस्तार होना चाहिए Ordered(या उसमें मिश्रण करना चाहिए), और इसलिए compareउस विशेषता को लागू करना चाहिए ।

तो किताब से एक उदाहरण को चीर देना:

class MyClass(n: Int) extends Ordered[MyClass] {
   ...
  def compare(that: MyClass) =
    this.n - that.n
}

इसलिए एक ऐरे [MyClass] दिया, फिर Sorting.quickSort पर काम करना चाहिए।


हाँ, यह एक है। यह समझ में आता है अब आप इसे इंगित करते हैं। मैं 'इसे' में कैसे मिलाऊँगा?
डैन ग्रेवेल

संपादित देखें। आप या तो मेरे उदाहरण की तरह विस्तार करते हैं, या "क्लास माईक्लास अन्य क्लैस को ऑर्डर किए गए [मायक्लास]" के साथ उपयोग करते हैं, जो एक मिक्स-इन है।
स्कैफमैन जूल 15'09

धन्यवाद। मुझे लगता है कि मैं बाद में करूँगा।
डेन ग्रेवेल

6
पांडित्यपूर्ण होने के लिए नहीं, लेकिन ... आपकी कक्षा को आदेशित का विस्तार करने की आवश्यकता नहीं है, यह पर्याप्त है कि आपकी कक्षा के दायरे में एक दृश्य (जिसे अंतर्निहित रूपांतरण के रूप में भी जाना जाता है) से कुछ ऐसा हो जो आदेशित का विस्तार करता है।
किम स्टेबेल

100

स्केल 2.8 या बाद में ऐसा करना संभव है:

List(3,7,5,2).sortWith(_ < _)

यह java.util.Arrays.sort , क्विकॉर्ट के कार्यान्वयन का उपयोग करता है ।


2
अंतर्निहित आदेश का उपयोग करना, यहां तक ​​कि कम: सूची (3,7,5,2)। scala.collection.immutable.LinearSeq के अनुसार .sorted
Utgarda

हम कैसे जानते हैं कि SortWith java.util.Arrays.sort का उपयोग कर रहा है? क्या उसके लिए कोई संदर्भ है?
डीपकिमो


यह थोड़ा अलग है कि मूल प्रश्न क्या पूछ रहा था। यह निश्चित रूप से एक नई सॉर्ट की गई सूची बनाने के लिए काम करता है (या मूल प्रश्न में दिए गए सरणी के रूप में) लेकिन सॉर्टविट मूल सूची या एरे को क्रमबद्ध करने के विपरीत एक नई वस्तु देता है।
रफ्फिंसन

57

आजकल यह भी काम करता है:

List(3,7,5,2).sorted


और मुझे लगता है कि रिवर्स में सॉर्ट करने के लिए, मुहावरेदार तरीका है List(3,7,5,2).sorted.reverse?
निक चम्मास

19

यदि आप केवल चीजों को क्रमबद्ध करना चाहते हैं, लेकिन विशेष रूप से सॉर्टिंग ऑब्जेक्ट से शादी नहीं करते हैं, तो आप सूची के क्रमबद्ध तरीके का उपयोग कर सकते हैं। यह एक तर्क के रूप में एक तुलनात्मक कार्य करता है, इसलिए आप इसका उपयोग उस प्रकार से कर सकते हैं जो आप चाहते हैं:

List("Steve", "Tom", "John", "Bob").sort((e1, e2) => (e1 compareTo e2) < 0)

List(1, 4, 3, 2).sort((e1, e2) => (e1 < e2))

सूची संभवतः सरणियों की तुलना में "अधिक खराब" के रूप में योग्य हैं।

स्काला एप डॉक्स से :

def सॉर्ट (lt: (A, A) => बूलियन): सूची [A]

Sort the list according to the comparison function <(e1: a, e2: a) =>

बूलियन, जो सही होना चाहिए iff e1 e2 से छोटा है।


हम्म, इसलिए सूची में एक क्रमबद्ध विधि है, लेकिन एरे नहीं है। कितना असंतोषजनक रूप से अनियमित। मैं जावा एपीआई से उस तरह की बकवास की उम्मीद करता हूं, लेकिन स्काला की नहीं।
स्कैफमैन जूल 15'09

मुझे यकीन है कि पता करने के लिए एक scala newb का बहुत अधिक है, लेकिन यह एक आवश्यक बुराई हो सकती है, यह देखते हुए कि Scala सभी जावा सामान के साथ संगतता बनाए रख रही है। दूसरी ओर, स्काला इतना जादू करता है, यह सामान्य है कि वह इसे और भी अधिक करना चाहता है!
16:00 पर पीटर रिकोर

5
सूची (...) सॉर्ट {_ <_} अधिक मुहावरेदार होगी।
डैनियल स्पिवक जूल

2
यह भी ध्यान देने योग्य है कि स्ट्रिंग परिभाषित करता है (एक अंतर्निहित रूपांतरण के माध्यम से) <विधि: "डेनियल" <"क्रिस" == झूठा
डैनियल स्पाइवक

11
बस जानकारी के लिए, स्कैला पर 2.9.1 सॉर्ट अपग्रेडेड लगता है, सॉर्ट का उपयोग करें
Jérôme

5
val array = Array((for(i <- 0 to 10) yield scala.util.Random.nextInt): _*)
scala.util.Sorting.quickSort(array)

स्काला की "डिफ़ॉल्ट" सरणी एक उत्परिवर्तित डेटा संरचना है, जो जावा के ऐरे के बहुत करीब है। सामान्यतया, इसका मतलब है कि एक "सरणी" बहुत स्काला-ईश नहीं है, यहां तक ​​कि परस्पर डेटा संरचनाएं भी जाती हैं। हालांकि यह एक उद्देश्य पूरा करता है। यदि सरणी आपकी आवश्यकता के लिए सही डेटा प्रकार है, तो आप इसे कैसे सॉर्ट करते हैं। ऑब्जेक्ट सॉर्टिंग पर अन्य छंटाई विधियां हैं, वैसे।

मुझे लगता है कि मुझे सिर्फ एहसास हुआ कि आपका प्रश्न क्या है ... आपको किसी भी अंतर्निहित पैरामीटर को पारित करने की आवश्यकता नहीं है (यह अंतर्निहित है, आखिरकार)। यह पैरामीटर यह कहने के लिए मौजूद है कि K को ऑर्डर किए गए [K] प्रकार में बदलने का कोई तरीका होना चाहिए। ये परिभाषा पहले से ही स्काला की कक्षाओं के लिए मौजूद हैं, इसलिए आपको उनकी आवश्यकता नहीं है।

एक मनमाने वर्ग के लिए आप इसे इस तरह परिभाषित कर सकते हैं:

scala> case class Person(name: String)
defined class Person

scala> val array = Array(Person("John"), Person("Mike"), Person("Abe"))
array: Array[Person] = Array(Person(John), Person(Mike), Person(Abe))

scala> scala.util.Sorting.quickSort(array)
<console>:11: error: no implicit argument matching parameter type (Person) => Ordered[Person] was found.
       scala.util.Sorting.quickSort(array)
                                   ^
scala> class OrderedPerson(val person: Person) extends Ordered[Person] {
     | def compare(that: Person) = person.name.compare(that.name)
     | }
defined class OrderedPerson

scala> implicit def personToOrdered(p: Person) = new OrderedPerson(p)
personToOrdered: (p: Person)OrderedPerson

scala> scala.util.Sorting.quickSort(array)

scala> array
res8: Array[Person] = Array(Person(Abe), Person(John), Person(Mike))

अब, अगर व्यक्ति को शुरू करने का आदेश दिया गया था, तो यह समस्या नहीं होगी:

scala> case class Person(name: String) extends Ordered[Person] {
     | def compare(that: Person) = name.compare(that.name)
     | }
defined class Person

scala> val array = Array(Person("John"), Person("Mike"), Person("Abe"))
array: Array[Person] = Array(Person(John), Person(Mike), Person(Abe))

scala>  scala.util.Sorting.quickSort(array)

scala> array
res10: Array[Person] = Array(Person(Abe), Person(John), Person(Mike))

माफी, मैं स्पष्ट नहीं था: मुझे मनमाने ढंग से वस्तुओं की एक सरणी को सॉर्ट करने की आवश्यकता है, संख्या नहीं।
डैन ग्रेवेल

3

हालांकि स्वीकृत उत्तर गलत नहीं है, क्विकॉर्ट विधि इससे अधिक लचीलापन प्रदान करती है। मैंने आपके लिए यह उदाहरण लिखा है।

import System.out.println
import scala.util.Sorting.quickSort

class Foo(x:Int) {
def get = x
}

//a wrapper around Foo that implements Ordered[Foo]
class OrdFoo(x:Foo) extends Ordered[Foo] {
def compare(that:Foo) = x.get-that.get
}
//another wrapper around Foo that implements Ordered[Foo] in a different way
class OrdFoo2(x:Foo) extends Ordered[Foo] {
def compare(that:Foo) = that.get-x.get
}
//an implicit conversion from Foo to OrdFoo
implicit def convert(a:Foo) = new OrdFoo(a)

//an array of Foos
val arr = Array(new Foo(2),new Foo(3),new Foo(1))

//sorting using OrdFoo
scala.util.Sorting.quickSort(arr)
arr foreach (a=>println(a.get))
/*
This will print:
1
2
3
*/

//sorting using OrdFoo2
scala.util.Sorting.quickSort(arr)(new OrdFoo2(_))
arr foreach (a=>println(a.get))
/*
This will print:
3
2
1
*/

यह दिखाता है कि अलग-अलग क्रमबद्ध ऑर्डर प्राप्त करने के लिए फू से कुछ वर्ग तक निहित और स्पष्ट रूपांतरण का उपयोग कैसे किया जा सकता है।


2

मुझे उपयोगकर्ता सॉर्टिंग उपयोग पसंद है

उदाहरण :

val arr = Array(7,5,1, 9,2)

scala.util.Sorting.quickSort(arr)

कृपया अधिक जानकारी सॉर्टिंग उपयोग के लिए इसे पढ़ें


वर्तमान डॉक्स के बजाय पुराने 2.9.0 एपीआई डॉक्स का लिंक क्यों ?
jwvh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.