1

My json file contains arrays of ints and strings and objects. Is there a way of compressing the output of arrays that contain only ints or strings?

  • either do not display elements of these arrays, or
  • show type of elements and count

This is what it looks like now:

$ jq "." foo.json
{
    "version": [
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.3",
            "2.53.3",
            "2.53.0",
            "2.53.0",
            "2.53.3",
            "2.53.0",
            "2.53.0",
            "2.53.3",
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.0",
            "2.53.3",
            "2.53.0"
          ],
    "walltime_seconds": [
            0.165,
            0.199,
            0.415,
            0.193,
            12.114,
            0.227,
            12.341,
            12.145,
            0.135,
            0.326,
            0.293,
            0.19,
            0.271,
            0.103,
            0.196,
            0.18,
            0.177,
            0.166,
            0.506,
            0.568
          ]
}

This is what I would like:

{
    "version": "[..]",
    "walltime_seconds": "[..]",

}

or this

{
    "version": "Array(str, 20)",
    "walltime_seconds": "Array(float, 20)",

}

Of course the compression should happen anywhere in the json tree and it should only be done for int, str, float and not for objects.

peak
  • 105,803
  • 17
  • 152
  • 177
Leevi L
  • 1,538
  • 2
  • 13
  • 28

1 Answers1

3

This will do it:

def compress:
  if type == "array"
  then (if    all(.[]; type == "string") then "[string]"
        elif  all(.[]; type == "number") then "[number]"
        elif  all(.[]; type == "boolean") then "[boolean]"
        else .
        end)
  else .
  end;

walk(compress)

With your sample input, the result would be:

{
  "version": "[string]",
  "walltime_seconds": "[number]"
}

To include the length and handle arrays of null:

def compress:
  def check($t):
    if all(.[]; type == $t) then "[\($t)[\(length)]]" else empty end;
  if type == "array"
  then check("string") // check("number") // check("boolean") // check("null") // .
  else .
  end;
peak
  • 105,803
  • 17
  • 152
  • 177