Как отсортировать массив в Scala?

Я вижу там сортирующий объект Sorting с quicksort, quickSort, на нем.

Каким будет пример кода для его использования, сортировка массива объекта произвольного типа? Похоже, мне нужно передать реализацию признака Orderable, но я не уверен в синтаксисе.

Кроме того, я бы предпочел, чтобы ответы на это выполнялись "Scala way". Я знаю, что могу просто использовать библиотеку Java.

Ответ 1

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 должен работать.

Ответ 2

С Scala 2.8 или новее можно сделать:

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

который использует java.util.Arrays.sort, реализацию quicksort.

Ответ 3

В настоящее время это тоже работает:

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

Ответ 4

Если вы просто хотите сортировать вещи, но не вступаете в брак с объектом Сортировка, в частности, вы можете использовать метод сортировки 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) = > Boolean): Список [A]

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

Boolean, который должен быть истинным, если e1 меньше е2.

Ответ 5

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

Scala "default" array - изменяемая структура данных, очень близкая к Java Array. Вообще говоря, это означает, что "массив" не очень похож на Scala -ish, даже когда изменяются структуры данных. Тем не менее, это служит цели. Если массив является подходящим типом данных для ваших нужд, тогда вы его сортируете. Кстати, существуют другие методы сортировки по сортировке объектов.

Я думаю, что я только понял, в чем ваш вопрос... вам не нужно передавать какой-либо неявный параметр (в конце концов это подразумевается). Этот параметр существует, чтобы сказать, что должен быть какой-то способ преобразования типа 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))

Теперь, если Person был Ordered для начала, это не будет проблемой:

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

Хотя принятый ответ не является ошибочным, метод 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 в некоторый класс, расширяемый Ordered [Foo], могут использоваться для получения разных порядков сортировки.

Ответ 7

Я предпочитаю пользователя Сортировка util

Пример:

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

scala.util.Sorting.quickSort(arr)

пожалуйста, прочитайте это для получения дополнительной информации Сортировка утилиты