代码之家  ›  专栏  ›  技术社区  ›  Dan Gravell

如何对scala中的数组进行排序?

  •  79
  • Dan Gravell  · 技术社区  · 15 年前

    我看到有一个排序对象, Sorting ,用 quicksort 方法, quickSort ,就在上面。

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

    另外,我更喜欢用“scala方式”来回答这个问题。我知道我只能使用Java库。

    7 回复  |  直到 7 年前
        1
  •  32
  •   skaffman    15 年前

    sorting.quicksort声明了用于获取数字或字符串数组的函数,但我假设您的意思是要对自己类的对象列表进行排序?

    我想你看到的功能是

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

    如果我正确阅读,这意味着数组中的对象必须具有 Ordered 特质。所以你的课必须延长 命令 (或必须将其混合),因此必须实现 compare 这种特性的方法。

    所以从书中摘取一个例子:

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

    因此,给定一个数组[MyClass],那么sorting.quicksort应该可以工作。

        2
  •  97
  •   adelarsq    9 年前

    对于scala 2.8或更高版本,可以执行以下操作:

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

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

        3
  •  52
  •   hendrik    12 年前

    现在这一个也可以工作了:

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

        4
  •  19
  •   Peter Recore    15 年前

    如果您只想对事物进行排序,但还没有与排序对象结合,那么您可以使用列表的排序方法。它将比较函数作为参数,因此您可以在任何类型上使用它:

    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)=>布尔值): 表[A]

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

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

        5
  •  5
  •   Daniel C. Sobral    15 年前
    val array = Array((for(i <- 0 to 10) yield scala.util.Random.nextInt): _*)
    scala.util.Sorting.quickSort(array)
    

    斯卡拉的“默认”数组是一个可变的数据结构,非常接近Java的数组。一般来说,这意味着“数组”不是很有规模的,即使是可变的数据结构。不过,这是有目的的。如果数组是适合您需要的数据类型,那么您就是这样对它进行排序的。顺便说一下,在对象排序上还有其他的排序方法。

    我想我刚刚意识到你的问题是什么…您不需要传递任何隐式参数(毕竟它是隐式的)。该参数的存在意味着必须有某种方法将类型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))
    
        6
  •  3
  •   Kim Stebel    15 年前

    虽然接受的答案是正确的,但QuickSort方法提供了比这更大的灵活性。我为你写了这个例子。

    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到某个扩展有序[foo]的类来获得不同的排序顺序。

        7
  •  2
  •   Ahmad Al-Kurdi    7 年前

    我更喜欢用户 排序效用

    例子:

    val arr = Array(7,5,1, 9,2)
    
    scala.util.Sorting.quickSort(arr)
    

    请看这个了解更多信息 Sorting util