Sort tuples by inverse of the first element, regular second element

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

I want to define an order that sorts tuples in the following order:

  1. Boolean - reverse order

  2. Int - reverse order

  3. String - Normal Order

Example:

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

The order should be:

 (true, 5, "cc") (false, 8,"zz") (false, 3, "bb") (false, 3, "dd") 

I could not find a way to determine some of the ordering and some regular ones.

+8
source share
2 answers

A direct solution in this particular case is to use sortBy in tuples modified on the fly to “invert” the first and second elements so that the order is finally canceled:

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

In cases where you cannot easily “invert” the value (say that it is a reference object and you have an opaque order on them), you can instead use sorted and explicitly pass the ordering that is built to invert the order on the first and second elements (you can use Ordering.reverse to reverse the order):

 val myOrdering: Ordering[(Boolean, Int, String)] = Ordering.Tuple3(Ordering.Boolean.reverse, Ordering.Int.reverse, Ordering.String) a.sorted(myOrdering) 
+11
source

You could do something like this.

 case class myTuple(t: (Boolean, Int, String)) extends Ordered[myTuple] { def compare(that: myTuple):Int = { val (x,y,z) =t val (x1,y1,z1) = that.t if (x.compare(x1) != 0) x.compare(x1) else { if (y.compare(y1) != 0) if (y.compare(y1) == 1) 0 else 1 else z.compareTo(z1) } } } val myList = Array((false, 8, "zz"), (false,3, "bb"), (true, 5, "cc"),(false, 3,"dd")) implicit def tupleToBeordered(t: (Boolean, Int, String)) = new myTuple(t._1,t._2,t._3) myList.sorted 
-1
source

Source: https://habr.com/ru/post/988426/


All Articles