Groovy collect from map and submap

与世无争的帅哥 提交于 2020-05-16 03:54:31

问题


I had a requirement to convert a JSON response into a csv file. I was able to successfully use Tim Yates' excellent code from here: Groovy code to convert json to CSV file

I now need to include the JSON's nested submap in the csv as well. The relationship between the map and submap is 1:1.

I've been unable to get the correct syntax for a collect statement that will retrieve both the parsed map and submap key/values.

Sample JSON

{items=
[
{ 
  created_at=2019-03-27
, entity_id=1
, extension_attributes=[]
},

{
  created_at=2019-03-27
, entity_id=2
, extension_attributes= { employee_id=Emp1, employee_type=CSR}//nested submap
}
]}

Groovy

import groovy.json.*

def data = new JsonSlurper().parseText( json ); //"json" is from GET request

def columns = ["created_at","entity_id","employee_id","employee_type"]

def encode = { e -> e ? /"$e"/ : "$e"}

requestFile.append( columns.collect { c -> encode( c ) }.join( ',' ) + '\n');

requestFile.append( data.items.collect { row ->columns.collect { colName -> encode( row[ colName ] ).replaceAll("null","") }.join( ',' )}.join( '\n' ) );//unsure how to use data.items.collect to fetch submap

I would like to either 1) Convert the JSON as follows to collect each key/value easily:

...
{
  created_at=2019-03-27
, entity_id=2
, employee_id=Emp1
, employee_type=CSR
}
...

or 2) Find out if there's a way to use Groovy's collect method to retrieve the map/submap as a flat map.

I am unfortunately not a programmer by trade, and any help would be appreciated!


回答1:


Here is the flatten closure which flattens an item recursively:

def flatten
flatten = { row ->
    def flattened = [:]
    row.each { k, v ->
        if (v instanceof Map) {
            flattened << flatten(v)
        } else {
            flattened[k] = v
        }
    }
    flattened
}

You should just replace row with flatten(row) at your last line so it looks like this:

requestFile.append(data.items.collect { row ->
    columns.collect {
        colName -> encode(flatten(row)[colName]).replaceAll("null", "")
    }.join(',')
}.join('\n'))

The result will be as follows:

"created_at","entity_id","employee_id","employee_type"

"2019-03-27","1",,
"2019-03-27","2","Emp1","CSR"



回答2:


Also found that following allows for collect method to fetch nested elements:

def m = data.items.collect{[/"${it?.created_at?:''}"/,/"${it?.extension_attributes?.entity_id?:''}"/,/"${it?.extension_attributes?.employee_id?:''}"/,/"${it?.extension_attributes?.employee_type?:''}"/]}

m.each{requestFile.append(it.join(',')+'\n')}


来源:https://stackoverflow.com/questions/55387405/groovy-collect-from-map-and-submap

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!