How to deconstruct sort method for length of strings (descending) in Scala?

Viewed 165

I came across this piece of code that sorts a collection of strings in descending order by length:

words.sortBy(x => -x.length)

Can someone help me to understand what the purpose of - in front of x is and deconstruct this code piece by piece? Is it standing for 'reverse' operation? I know it's integer operation but I'm having a hard time figuring out how the algorithm works in the background. Also can this be deemed a bubble sort?

1 Answers

If you have:

val collection: SomeCollection[A]
val keyToSortBy A => B

when you do:

collection.sortBy(keyToSortBy)

what happens is that Scala will look for Ordering[B] in its implicit scope (read about implicits if you aren't familiar with them yet), and it will use methods provided by this interrface to compare elemetns by sorting algorithm.

sortBy will use Ordering[X] to sort things in ascending order (think Comparator if you know Java). For Ordering[Int] it's just increasing order of integers, for Ordering[String] you have a lexical order of Strings.

What - does here is taking the value before passing it to the algorithm sorting by Int and negating it. It would be easier if you see some example:

List("a", "bb", "ccc").sortBy(word => word.length)
// imagine that what it does is:
// - building a collection of pairs ("a", 1), ("bb", 2), ("ccc", 3)
//   ( (value from collection, what function returned for that value) )
// - sorting by the second element of pair
//   using normal Int comparison to get ascending result
// - take only the first element of each pair: ("a", 1), ("bb", 2), ("ccc", 3)
List("a", "bb", "ccc") // result

If we put - there, what Ordering would get to compate would be different:

List("a", "bb", "ccc").sortBy(word => -word.length)
// - building a collection of pairs ("a", -1), ("bb", -2), ("ccc", -3)
// - sorting by the second element of pair - notice that all are negative now!!!
//   using normal Int comparison to get ascending result
// - take only the first element of each pair: ("ccc", -3), ("bb", -2), ("a", -1)
List("ccc", "bb", "a") // result
Related