I have an Array{Tuple{Float64, Int}}
, I want to sort it in reversed order according to the first entries and in straight order according to the second one.
Example: if a=[(1.0,2),(3.0,1),(2.0,3),(2.0,2)]
, after calling sort!(a, ...)
, I'd like to get [(3.0,1),(2.0,2),(2.0,3),(1.0,2)]
where the first dimension is sorted from greater values to smaller ones and, when two entries are equal, the second dimension is sorted from small to big.
There are a couple ways to customize the sorting order, using either the lt
or by
keyword arguments to sort
(or sort!
):
lt
: you define a custom "less-than" operator for tuples. You encode in this comparison operator more or less the order as you'd express it in a plain way:julia> a=[(1.0,2),(3.0,1),(2.0,3),(2.0,2)];
julia> mylt((x1,y1), (x2,y2)) = x1>x2 || (x1==x2 && y1<y2)
mylt (generic function with 1 method)
julia> sort(a, lt=mylt)
4-element Array{Tuple{Float64,Int64},1}:
(3.0, 1)
(2.0, 2)
(2.0, 3)
(1.0, 2)
2.using by
: you define a transformation that is applied to each element in the array, and by which elements are sorted:
julia> x_desc_then_y_asc((x,y)) = (-x, y)
x_desc_then_y_asc (generic function with 1 method)
julia> sort(a, by=x_desc_then_y_asc)
4-element Array{Tuple{Float64,Int64},1}:
(3.0, 1)
(2.0, 2)
(2.0, 3)
(1.0, 2)
The helper function in that variant is so short that I would make an anonymous function out of it:
julia> sort(a, by=((x,y),)->(-x,y))
4-element Array{Tuple{Float64,Int64},1}:
(3.0, 1)
(2.0, 2)
(2.0, 3)
(1.0, 2)
PS: note how "tuple destructuring" is used in all these examples in order to avoid indexing explicitly into tuples.