Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sort tuples by first element reverse, second element regular

Tags:

sorting

scala

I have tuples of the form (Boolean, Int, String).

I want to define Ordering which sorts the tuples in the following order:

  1. Boolean - reverse order

  2. Int - reverse order

  3. String - regular order

Example:

For the tuples: Array((false, 8, "zz"), (false,3, "bb"), (true, 5, "cc"),(false, 3,"dd")).

The ordering should be:

(true, 5, "cc")

(false, 8,"zz")

(false, 3, "bb")

(false, 3, "dd")

I couldn't find a way to define some of the ordering reverse and some regular.

like image 489
mayap Avatar asked Jun 03 '15 05:06

mayap


People also ask

How do you sort a tuple in reverse order?

Using sorted() We can use a tuple to convert this list data type to a tuple (). The reverse parameter to the sorted() function can also specify the sorting order. Ascending is the default sorting order. The items are sorted in descending order when reverse=True is set.

How do you sort a list of tuples in Python by first and second element?

To sort a list of tuples by multiple elements in Python: Pass the list to the sorted() function. Use the key argument to select the elements at the specific indices in each tuple. The sorted() function will sort the list of tuples by the specified elements.

How do you sort a tuple based on the second element?

Use the key argument of the sorted() function to sort a list of tuples by the second element, e.g. sorted_list = sorted(list_of_tuples, key=lambda t: t[1]) . The function will return a new list, sorted by the second tuple element. Copied!

How do you sort a list of tuples by a value in the tuple?

Therefore, we can simply use the sort() method to sort a list. First, we will take an unsorted list of tuples and then call the sort() method. The sort() method will change the order from increasing (ascending) to decreasing (descending) when we pass the parameter reverse=True as an argument.


1 Answers

The straight forward solution in this specific case is to use sortBy on the tuples, modified on the fly to "invert" the first and second elements so that in the end the ordering is reversed:

val a = Array((false, 8, "zz"), (false,3, "bb"), (true, 5, "cc"),(false, 3,"dd"))
a.sortBy{ case (x,y,z) => (!x, -y, z) }

For cases when you cannot easily "invert" a value (say that this is a reference object and you've got an opaque ordering on them), you can instead use sorted and explicitly pass an ordering that is constructed to invert the order on the first and second elements (you can use Ordering.reverse to reverse an ordering):

val myOrdering: Ordering[(Boolean, Int, String)] = Ordering.Tuple3(Ordering.Boolean.reverse, Ordering.Int.reverse, Ordering.String)
a.sorted(myOrdering)
like image 53
Régis Jean-Gilles Avatar answered Oct 27 '22 16:10

Régis Jean-Gilles