Comment sortinger un tableau dans Scala?

Je peux voir un object de sorting, Sorting , avec une méthode de Sorting rapide , quickSort , sur celui-ci.

Quel serait un exemple de code d’utilisation, sortingant un tableau d’object de type arbitraire? Il semble que je doive passer à une implémentation du trait Orderable , mais je ne suis pas certain de la syntaxe.

De plus, je préférerais des réponses faisant cela à la «manière Scala». Je sais que je peux simplement utiliser une bibliothèque Java.

Sorting.quickSort déclare des fonctions pour prendre un tableau de nombres ou de chaînes, mais je suppose que vous voulez dire que vous voulez sortinger une liste d’objects de vos propres classes?

La fonction que je pense que vous regardez est

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

Lequel, si je lis bien, signifie que les objects du tableau doivent avoir le caractère Ordered . Donc, votre classe doit étendre Ordered (ou doit le mélanger), et doit donc implémenter la méthode de compare de ce trait.

Donc, pour extraire un exemple du livre:

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

Donc, étant donné un tableau [MyClass], alors Sorting.quickSort devrait fonctionner.

Avec Scala 2.8 ou version ultérieure, il est possible de faire:

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

qui utilise java.util.Arrays.sort , une implémentation de quicksort.

De nos jours, celui-ci fonctionne aussi:

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

Si vous voulez simplement sortinger les choses, mais que vous n’êtes pas marié à l’object Tri en particulier, vous pouvez utiliser la méthode de sorting de List. Il prend une fonction de comparaison comme argument, vous pouvez donc l’utiliser sur tous les types que vous souhaitez:

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

Les listes sont probablement qualifiées de "plus scalaish" que les tableaux.

De la scala api docs :

def sort (lt: (A, A) => Booléen): Liste [A]

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

Booléen, qui devrait être vrai si e1 est plus petit que e2.

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

Le tableau "par défaut" de Scala est une structure de données mutable, très proche de celle de Java. D'une manière générale, cela signifie qu'un "tableau" n'est pas très Scala-ish, même lorsque les structures de données mutables disparaissent. Cela sert un but, cependant. Si array est le bon type de données pour votre besoin, alors c'est comme ça que vous le sortingez. Au fait, il existe d’autres méthodes de sorting sur les objects.

Je pense que je viens de réaliser votre question ... vous n'avez pas besoin de passer de paramètre implicite (implicite, après tout). Ce paramètre existe pour dire qu'il doit y avoir un moyen de convertir le type K en un ordonné [K]. Ces définitions existent déjà pour les classes de Scala, vous n'en avez donc pas besoin.

Pour une classe arbitraire, vous pouvez la définir de la manière suivante:

 scala> case class Person(name: Ssortingng) 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) :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)) 

Maintenant, si la personne a été commandée pour commencer, cela ne serait pas un problème:

 scala> case class Person(name: Ssortingng) 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)) 

Bien que la réponse acceptée ne soit pas fausse, la méthode de sorting rapide offre plus de flexibilité que cela. J’ai écrit cet exemple pour vous.

 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 */ 

Cela montre comment les conversions implicites et explicites de Foo en une classe élargissant Ordered [Foo] peuvent être utilisées pour obtenir différents ordres de sorting.

Je préfère utiliser les utilisateurs

Exemple :

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

veuillez lire ceci pour plus d’informations