2

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?

5
  • 1
    sortBy takes a function that transforms each element in the input collection, into something which will determine the order on which the elements will be sorted ascending. In this case, you are sorting the words by their lengths. Since the sort is ascending and lengths are numbers, this means that it will start with the length which is smaller. But, you want them descending, so one option is to use a reverse ordering, or by just making the lengths negative, then the larger the length, it becomes smaller so the final sort results in descending order. Commented Apr 1, 2020 at 15:10
  • @luis So the => begins with the lowest number by default as per sortBy method, and then looks for the next biggest? Commented Apr 1, 2020 at 15:19
  • 1
    => doesn't have anything to do with the sorting. It is the syntax for a lambda (and anonymous function). Commented Apr 1, 2020 at 15:23
  • 2
    I suspected that someone will be wondering about this when I read Krever's tweet :D (twitter.com/Krever01/status/1244922189121499136) Commented Apr 1, 2020 at 15:42
  • 1
    @MateuszKubuszok you got me! Good spot by you. Commented Apr 1, 2020 at 16:02

1 Answer 1

6

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
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.