1

I have the following JSON records stored in a container

{"memberId":123,"memberCity":"Chicago","lastTransaction":1504155600000}
{"memberId":123,"memberCity":"Chigago","lastTransaction":150175600000}
{"memberId":123,"memberCity":"New York","lastTransaction":150195600000}

I am looking to validate that the sort order in which these records are stored are sorted by memberId ASC, memberCity ASC, lastTransaction ASC

Is there a way via jq that I can assert (true/false) the sort order, taking multiple fields into account?

peak
  • 105,803
  • 17
  • 152
  • 177
rs79
  • 2,311
  • 2
  • 33
  • 39

2 Answers2

4

Here's a reasonably efficient solution, presented in a way that hopefully makes it easy to understand and adapt:

def sorted:
  if length <= 1 then true
  else map([.memberId, .memberCity, .lastTransaction])
  | .[0] <= .[1]
  end;

def pairs(stream):
  foreach stream as $i ([]; 
    .[-1:] + [$i]; 
    select(length==2));


all(pairs(inputs); sorted)

Invocation:

jq -n -f sorted.jq input.json

If the stars are aligned properly and you want a one-liner:

jq 'all(foreach [inputs[]] as $i ([[.[]]]; [.[-1],$i]); .[0]<=.[1])' input.json

Season to taste.

peak
  • 105,803
  • 17
  • 152
  • 177
2

Any solution that requires using the -s command-line option has the drawback of requiring more memory than is needed. Similarly using sort is inadvisable in general, but if one wants a concise and simple solution, one could go with:

jq -s 'map([.memberId, .memberCity, .lastTransaction]) | . == sort' 

or even in the specific case given:

jq -s 'map(.[]) | . == sort' 
peak
  • 105,803
  • 17
  • 152
  • 177