takotsubo
takotsubo

Reputation: 746

Transpose JSON in Groovy

I have a JSON:

{
    "range": "'All traffic",
    "majorDimension": "ROWS",
    "values": [
        [
            "Date",
            "Sessions",
            "Leeds",
            "Сontact_query",
            "wo_Сontact_query"
        ],
        [
            "20200107",
            "3461",
            "15",
            "0",
            "15"
        ],
        [
            "20200115",
            "7824",
            "43",
            "0",
            "43"
        ]
    ]
}

Elements in values array with index[0] are names for JSON properties. I want to map these names with values starting with index[0+]. Number of values can be different for each index. Mapping should be dynamical, without hard indexing.

I want to get following JSON:

[
  {
    "Date": "20200107",
    "Sessions": "3461",
    "Leeds": "15",
    "Contact_query": "0",
    "wo_Contact_query": "15"
  },
  {
    "Date": "20200115",
    "Sessions": "7824",
    "Leeds": "43",
    "Contact_query": "0",
    "wo_Contact_query": "43"
  }
] 

I successfully did it with kinda weird JOLT config:

[
  {
    "operation": "shift",
    "spec": {
      "values": {
        "0": null,
        "*": {
          "*": "[&1].@(2,[0].[&])"
        }
      }
    }
  },
  {
    "operation": "shift",
    "spec": {
      "0": null,
      "*": "[]"
    }
  }
]

But i want to replace it with Groovy script.

I reached following solution:

def slurped = new JsonSlurper().parseText(text)

def val = slurped.values[0]

def json = slurped.values.collect{
  [val, it].transpose().collectEntries() 
}

But it also returns values for [0] element which one i should skip:

{
  "Date":"Date",
  "Sessions":"Sessions",
  "Leeds":"Leeds",
  "Contact_query":"Contact_query",
  "wo_Contact_query":"wo_Contact_query"
}

How can I improve solution?

Upvotes: 1

Views: 183

Answers (2)

Matias Bjarland
Matias Bjarland

Reputation: 4482

Another option using head and tail:

def json = new JsonSlurper().parseText(data)
def head = json.values.head() // first element, the "head"
def tail = json.values.tail() // the rest, excluding the head, i.e. "tail"
def result = tail.collect { [head, it].transpose().collectEntries() }

Upvotes: 1

Jérémie B
Jérémie B

Reputation: 11022

You can use pop to remove the first value of a collection:

def values = new groovy.json.JsonSlurper().parseText(text).values;
def val = values.pop()
def json = values.collect { [val, it].transpose().collectEntries()  }

Upvotes: 5

Related Questions