I have tuples of the form (Boolean, Int, String)
.
I want to define Ordering which sorts the tuples in the following order:
Boolean - reverse order
Int - reverse order
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.
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.
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.
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!
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With