Skip to content

flatten example does not flatten arrays #349

@samer1977

Description

@samer1977

Hi,
I noticed the flatten-objects function here doesnt flatten nested arrays. I understand that flattening can have different meaning & expectations depending on each use case but my expectation when I want to flatten a json that it should cover everything. Of course considering arrays can get very complex given what arrays can hold. Part of learning jslt I wanted to take on this challenge to see if it can be done. I hope I was successful but part of doing this I found myself using some other helpful functions (see comments on each function) that I thought it might be nice to have not just for flattening but for other things and maybe have them as built function. Without further due , here is the code:

// This is different way of zipping where the key is the index itself. I found that provide more direct way if you need to access the index
// vs storing the index in another key.
def zip-by-index(json)
  
  let res = if(is-array($json)) [for(zip-with-index($json)) {string(.index):.value}] else []
  $res

//This is to make an array as complex object to create uniformity on how complex types in json can be processed. Im not sure there are 
// many use cases for this but its nice to have as an option
def objectify-array(array)
 let res = if($array==[] or $array==null) {}
          else if(size($array)==1) $array[0]
          else $array[-1]+objectify-array($array[0 : -1])
 $res 

def flatten_json(prefix,json)

   let simple=  {for($json) $prefix+.key:.value if(.key!=null and not(is-object(.value)) and not(is-array(.value)))}
   let complex= [for($json)  flatten_json($prefix+.key+".",.value) if(is-object(.value))]
   let array= [for($json)  flatten_json($prefix+.key+".",objectify-array(zip-by-index(.value))) if(is-array(.value))]
   
   objectify-array($array)+objectify-array($complex)+$simple
    

flatten_json("",.)

Example:

{
  "x": "x1",
  "y": "y2",
  "z": {
    "z1": "z11",
    "z2": null,
    "z3": [
      1,
      {
        "zzz": "skid",
        "zzz1": null
      },
      2
    ]
  }
}

Output:

{
  "x" : "x1",
  "y" : "y2",
  "z.z1" : "z11",
  "z.z3.0" : 1,
  "z.z3.2" : 2,
  "z.z3.1.zzz" : "skid"
}

I appreciate any well explained feedback.
Thanks
S

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions