sociales redes mediatica informacion scala

redes - ¿Cuál es la mejor manera de ordenar inversa en Scala?



informacion mediatica (9)

¿Cuál es la mejor manera de hacer una clasificación inversa en scala? Me imagino que lo siguiente es algo lento.

list.sortBy(_.size).reverse

¿Existe una forma conveniente de utilizar sortBy pero obteniendo un orden inverso? Preferiría no necesitar usar sortWith .


Easy peasy (al menos en caso 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)


Otra posibilidad en caso de que pase una función que no podrá modificar directamente a un Arraybuffer mediante sortWith, por ejemplo:

val buf = collection.mutable.ArrayBuffer[Int]() buf += 3 buf += 9 buf += 1 // the sort function (may be passed through from elsewhere) def sortFn = (A:Int, B:Int) => { A < B } // the two ways to sort below buf.sortWith(sortFn) // 1, 3, 9 buf.sortWith((A,B) => { ! sortFn(A,B) }) // 9, 3, 1


Puede haber una forma obvia de cambiar el signo, si ordena por algún valor numérico

list.sortBy(- _.size)

De manera más general, la ordenación puede hacerse por método ordenado con un Pedido implícito, que puede explicitarse, y Ordenando tiene un reverso (no la lista al reverso más abajo) Puede hacer

list.sorted(theOrdering.reverse)

Si el orden que desea invertir es el orden implícito, puede obtenerlo implícitamente [Pedido [A]] (A del tipo que está ordenando) o mejor Orden [A]. Eso sería

list.sorted(Ordering[TheType].reverse)

sortBy es como usar Ordering.by, así que puedes hacer

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

Tal vez no sea el más corto para escribir (en comparación con menos) pero la intención es clara

Actualizar

La última línea no funciona. Para aceptar el _ en Ordering.by(_.size) , el compilador necesita saber en qué tipo estamos ordenando, para que pueda escribir el _ . Puede parecer que sería el tipo del elemento de la lista, pero esto no es así, ya que la firma del ordenado se def sorted[B >: A](ordering: Ordering[B]) . El orden puede estar en A , pero también en cualquier antecesor de A (puede usar byHashCode : Ordering[Any] = Ordering.by(_.hashCode) ). Y, de hecho, el hecho de que la lista sea covariante obliga a esta firma. Uno puede hacer

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

pero esto es mucho menos agradable.


Tanto sortWith como sortBy tienen una sintaxis compacta:

case class Foo(time:Long, str:String) val l = List(Foo(1, "hi"), Foo(2, "a"), Foo(3, "X")) l.sortWith(_.time > _.time) // List(Foo(3,X), Foo(2,a), Foo(1,hi)) l.sortBy(- _.time) // List(Foo(3,X), Foo(2,a), Foo(1,hi)) l.sortBy(_.time) // List(Foo(1,hi), Foo(2,a), Foo(3,X))

Encuentro que el que tiene sortWith más fácil de entender.


este es mi código;)

val wordCounts = logData.flatMap(line => line.split(" ")) .map(word => (word, 1)) .reduceByKey((a, b) => a + b) wordCounts.sortBy(- _._2).collect()


tal vez para acortarlo un poco más:

def Desc[T : Ordering] = implicitly[Ordering[T]].reverse List("1","22","4444","333").sortBy( _.size )(Desc)


sortBy tiene un parámetro implicit que proporciona ordenamiento

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

entonces, podemos definir el propio objeto Ordering

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)


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


val list = List(2, 5, 3, 1) list.sortWith(_>_) -> res14: List[Int] = List(5, 3, 2, 1) list.sortWith(_<_) -> res14: List[Int] = List(1, 2, 3, 5)