如何在Scala中对数组进行排序?

时间:2009-07-15 14:55:56

标签: sorting scala

我可以看到有一个排序对象Sorting,上面有quicksort方法,quickSort

使用它的代码示例是什么,对任意类型的对象数组进行排序?看起来我需要传递Orderable特征的实现,但我不确定语法。

另外,我更喜欢以“Scala方式”做到这一点的答案。我知道我可以使用Java库。

7 个答案:

答案 0 :(得分:98)

使用Scala 2.8或更高版本可以执行以下操作:

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

使用java.util.Arrays.sort,即快速排序的实现。

答案 1 :(得分:53)

现在这个也有效:

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

答案 2 :(得分: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
}

所以给定一个Array [MyClass],那么Sorting.quickSort应该可以工作。

答案 3 :(得分:19)

如果您只想对事物进行排序,但特别是与Sorting对象没有结合,则可以使用List的排序方法。它将比较函数作为参数,因此您可以在任何类型的函数中使用它:

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

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

列表可能比数组更符合“更多的scalaish”。

来自scala api docs

  

def sort(lt:(A,A)=&gt; Boolean):   列表[A]

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

布尔值,iff e1应为true   小于e2。

答案 4 :(得分:5)

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

Scala的“默认”数组是一个可变数据结构,非常接近Java的数组。一般来说,这意味着“数组”不是非常Scala-ish,即使可变数据结构也是如此。但它有一个目的。如果array是您需要的正确数据类型,那么这就是您对它进行排序的方式。顺便说一句,对象排序还有其他排序方法。

我想我刚刚意识到你的问题是什么......你不需要传递任何隐含的参数(毕竟它是隐含的)。该参数的存在表明必须有某种方法将类型K转换为有序[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))

现在,如果开始订购人员,这不会是一个问题:

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 :(得分: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
*/

这显示了从Foo到某些扩展Ordered [Foo]的类的隐式和显式转换如何用于获取不同的排序顺序。

答案 6 :(得分:2)

我更喜欢用户排序工具

示例:

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

scala.util.Sorting.quickSort(arr)

请阅读此内容以获取更多信息Sorting util