クイックソートメソッドがSorting
付いた並べ替えオブジェクトがあります。quickSort
それを使用して、任意のタイプのオブジェクトの配列をソートするコード例は何でしょうか?Orderable
トレイトの実装を渡す必要があるようですが、構文がわかりません。
また、私はこれを「スカラの方法」で行う答えを好みます。私はJavaライブラリを使用できることを知っています。
回答:
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
}
したがって、Array [MyClass]が与えられると、Sorting.quickSortが機能するはずです。
今日ではこれも機能します:
List(3,7,5,2).sorted
List(3,7,5,2).sorted.reverse
?
物事を並べ替えるだけで、特にSortingオブジェクトと結婚していない場合は、Listのsortメソッドを使用できます。引数として比較関数を使用するため、任意のタイプで使用できます。
List("Steve", "Tom", "John", "Bob").sort((e1, e2) => (e1 compareTo e2) < 0)
List(1, 4, 3, 2).sort((e1, e2) => (e1 < e2))
リストは、おそらく配列よりも「よりスカラッシュ」と見なされます。
Scala APIドキュメントから:
def sort(lt:(A、A)=>ブール値):List [A]
Sort the list according to the comparison function <(e1: a, e2: a) =>
ブール値。e1がe2よりも小さい場合はtrueになります。
val array = Array((for(i <- 0 to 10) yield scala.util.Random.nextInt): _*)
scala.util.Sorting.quickSort(array)
Scalaの「デフォルト」配列は変更可能なデータ構造であり、Javaの配列に非常に近いものです。一般的に言って、これは、可変データ構造が使用されている場合でも、「配列」はそれほどスカラっぽくないことを意味します。しかし、それは目的を果たします。配列がニーズに適したデータ型である場合は、それがソート方法です。ちなみに、オブジェクトの並べ替えには他の並べ替え方法があります。
私はあなたの質問が何であるかを理解したと思います...暗黙のパラメータを渡す必要はありません(結局のところ、暗黙のパラメータです)。そのパラメータは、タイプKをOrdered [K]に変換する何らかの方法が必要であることを示すために存在します。これらの定義はScalaのクラスにすでに存在するため、必要ありません。
任意のクラスについて、次のように定義できます。
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))
さて、Personが最初に注文された場合、これは問題にはなりません。
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))
受け入れられた答えは間違っていませんが、クイックソート方式はそれよりも柔軟性があります。私はあなたのためにこの例を書きました。
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
*/
これは、FooからOrdered [Foo]を拡張するクラスへの暗黙的および明示的な変換を使用して、さまざまな並べ替え順序を取得する方法を示しています。
私はユーザーのSortingutilを好む
例:
val arr = Array(7,5,1, 9,2)
scala.util.Sorting.quickSort(arr)
詳細は、これをお読みくださいソートのutil