133 votes

Quelle est la meilleure façon de faire un tri inverse en Scala ?

Quelle est la meilleure façon de faire un tri inverse en Scala ? J'imagine que la méthode suivante est quelque peu lente.

list.sortBy(_.size).reverse

Existe-t-il un moyen conveinent d'utiliser sortBy mais d'obtenir un tri inverse ? Je préférerais ne pas avoir à utiliser sortWith .

234voto

Didier Dupont Points 18256

Il existe un moyen évident de changer le signe, si vous triez par une valeur numérique.

list.sortBy(- _.size)

Plus généralement, le tri peut être fait par la méthode sorted avec un Ordering implicite, que vous pouvez rendre explicite, et l'Ordering a un reverse (pas le reverse de liste ci-dessous) Vous pouvez faire

list.sorted(theOrdering.reverse)

Si l'ordonnancement que vous voulez inverser est l'ordonnancement implicite, vous pouvez l'obtenir par implicitement [Ordering[A]] (A le type sur lequel vous ordonnez) ou mieux Ordering[A]. Ce serait

list.sorted(Ordering[TheType].reverse)

sortBy est comme l'utilisation de Ordering.by, vous pouvez donc faire

list.sorted(Ordering.by(_.size).reverse)

Peut-être pas le plus court à écrire (par rapport aux moins) mais l'intention est claire.

Mise à jour

La dernière ligne ne fonctionne pas. Pour accepter le _ sur Ordering.by(_.size) le compilateur a besoin de savoir quel type nous commandons, afin qu'il puisse taper l'élément _ . Il peut sembler que ce serait le type de l'élément de la liste, mais ce n'est pas le cas, car la signature de trié est def sorted[B >: A](ordering: Ordering[B]) . La commande peut se faire sur A mais aussi sur tout ancêtre de A (vous pouvez utiliser byHashCode : Ordering[Any] = Ordering.by(_.hashCode) ). Et en effet, le fait que la liste soit covariante force cette signature. On peut faire

list.sorted(Ordering.by((_: TheType).size).reverse)

mais c'est beaucoup moins agréable.

109voto

incrop Points 1437
list.sortBy(_.size)(Ordering[Int].reverse)

27voto

Bruno Bieth Points 515

Peut-être pour le raccourcir un peu plus :

def Desc[T : Ordering] = implicitly[Ordering[T]].reverse

List("1","22","4444","333").sortBy( _.size )(Desc)

19voto

om-nom-nom Points 33691

Easy peasy (au moins dans le cas de size ) :

scala> val list = List("abc","a","abcde")
list: List[java.lang.String] = List(abc, a, abcde)

scala> list.sortBy(-_.size)
res0: List[java.lang.String] = List(abcde, abc, a)

scala> list.sortBy(_.size)
res1: List[java.lang.String] = List(a, abc, abcde)

9voto

4e6 Points 5970

sortBy a un paramètre implicite ord qui permet de commander

def sortBy [B] (f: (A) ⇒ B)(implicit ord: Ordering[B]): List[A]

ainsi, nous pouvons définir notre propre Ordering objet

scala> implicit object Comp extends Ordering[Int] {
 | override def compare (x: Int, y: Int): Int = y - x
 | }
defined module Comp

List(3,2,5,1,6).sortBy(x => x)
res5: List[Int] = List(6, 5, 3, 2, 1)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X