Home > Blockchain >  How to compress output of arrays of primitive type?
How to compress output of arrays of primitive type?

Time:04-23

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.

CodePudding user response:

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;
  • Related