Home > Enterprise >  How to sort_by in descending order without reverse in jq
How to sort_by in descending order without reverse in jq

Time:10-14

When you have a columns and want to sort by multiple columns in various orders - you will start chaining reverses

my jq sort_by is stable, but if i need to sort by descending - I have to do double reverse, which i dont like

sort_by(.person) # first sort in ascending
| reverse | sort_by(.city) | reverse # then sort by in descending

In order to keep both city descending and person ascending, (but by city) - I feel like I need double reverse, so this api does not looks good, in terms of performance for advanced sorting.

Do you know any workaround, not using double reverse?

CodePudding user response:

More of an idea than a good solution, but you could sort by negative codepoints obtained by using explode. At least there's no reverse involved, and only one call to sort_by is needed for all criteria.

sort_by(.person, (.city | [-explode[]]))

CodePudding user response:

Quicksort is not stable, but ...

def reverse_quicksort_by(f):
  def r:
    if length < 2 then .
    else (.[0]|f) as $pivot
    | reduce .[] as $x
        # state: [less, equal, greater]
        ( [ [], [], [] ];
        ($x|f) as $y
        | if   $y  < $pivot then .[0] = [$x]   .[0]  # add x to less
          elif $y == $pivot then .[1]  =  [$x]       # add x to equal
          else  .[2] = [$x]   .[2]                   # add x to greater
          end )
      | (.[2] | r )    .[1]   (.[0] | r )
    end ;
  r;

This has been tested with both the C and Go implementations (jq and gojq).

  • Related