web-dev-qa-db-ja.com

Scalaで配列をソートするにはどうすればよいですか?

ソートオブジェクトSortingがあり、その上に quicksort メソッド、quickSortがあります。

それを使用して、任意のタイプのオブジェクトの配列をソートするコード例は何でしょうか? Orderableトレイトの実装を渡す必要があるように見えますが、構文がわかりません。

また、私はこれを「Scalaの方法」で行う答えを好むでしょう。 Javaライブラリ。

80
Dan Gravell

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が機能するはずです。

32
skaffman

Scala 2.8以降では、次のことが可能です。

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

Java.util.Arrays.sort 、クイックソートの実装を使用します。

98
adelarsq

最近では、これも機能します。

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

54
hendrik

単にソートしたいが、特にSortingオブジェクトと結婚していない場合は、Listのソート方法を使用できます。比較関数を引数として受け取るため、任意の型で使用できます。

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

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

リストはおそらく配列よりも「よりスケーラブル」と見なされます。

scala api docs から:

def sort(lt:(A、A)=> Boolean):List [A]

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

ブール値。e1がe2より小さい場合に真になります。

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

Scalaの「デフォルト」配列は、Javaの配列に非常に近い可変データ構造です。一般的に言えば、それは「可変配列」が、たとえ可変データ構造が行くとしても、あまりScalaっぽくないことを意味します。ただし、目的には役立ちます。配列がニーズに合った適切なデータ型である場合、それがソート方法です。ところで、オブジェクトの並べ替えには他の並べ替え方法があります。

私はちょうどあなたの質問が何であるかを理解したと思います...あなたは暗黙のパラメータを渡す必要はありません(結局は暗黙的です)。このパラメーターは、タイプ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))
5

受け入れられた答えは間違っていませんが、クイックソート方法はそれよりも柔軟性があります。この例を作成しました。

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]を拡張するクラスへの暗黙的および明示的な変換を使用して、異なる並べ替え順序を取得する方法を示しています。

3
Kim Stebel

私はユーザーを好むutilのソート

例:

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

scala.util.Sorting.quickSort(arr)

詳しくはこちらをお読みください Sorting util

2
Ahmad Al-Kurdi