При использовании Groovy требуется собрать значения вложенных элементов карты вместе со значением элемента верхнего уровня.
Не уверен, нужен ли рекурсивный метод.
Пример JSON
{
"items": [
{
"attribute": "Type",
"options":
[
{
"label": "Type1",
"value": "1"
},
{
"label": "Type2",
"value": "2"
}
]
},
{
"attribute": "Size",
"options": [
{
"label": "SizeA",
"value": "A"
},
{
"label": "SizeB",
"value": "B"
}
]
}
]
}
Ожидаемый результат после сбора
[
{attribute=Type,label=Type1,value=1},
{attribute=Type,label=Type2,value=2},
{attribute=Size,label=SizeA,value=A},
{attribute=Size,label=SizeB,value=B}
]
Вы можете решить эту проблему, объединив несколько списков options
, полученных с помощью метода собирать, используя собиратьмного.
См. следующий фрагмент кода:
def input = """
{
"items": [
{
"attribute": "Type",
"options": [
{
"label": "Type1",
"value": "1"
},
{
"label": "Type2",
"value": "2"
}
]
},
{
"attribute": "Size",
"options": [
{
"label": "SizeA",
"value": "A"
},
{
"label": "SizeB",
"value": "B"
}
]
} ]
}"""
def json = new groovy.json.JsonSlurper().parseText(input)
/* collectMany directly flatten the two sublists
* [ [ [ type1 ], [ type2 ] ], [ [ sizeA ], [ sizeB ] ] ]
* into
* [ [type1], [type2], [sizeA], [sizeB] ]
*/
def result = json.items.collectMany { item ->
// collect returns a list of N (in this example, N=2) elements
// [ [ attribute1: ..., label1: ..., value1: ... ],
// [ attribute2: ..., label2: ..., value2: ... ] ]
item.options.collect { option ->
// return in [ attribute: ..., label: ..., value: ... ]
[ attribute: item.attribute ] + option
}
}
assert result == [
[ attribute: "Type", label: "Type1", value: "1" ],
[ attribute: "Type", label: "Type2", value: "2" ],
[ attribute: "Size", label: "SizeA", value: "A" ],
[ attribute: "Size", label: "SizeB", value: "B" ],
]
Спасибо Джузеппе! Я решил это, используя менее groovy метод:
def result = [];//Create new list with top-level element and nested elements
json.items.each {item ->
result.addAll(item.options.collect{ option ->
[attribute: /"${item?.attribute?:''}"/, label: /"${option?.label?:''}"/, value: /"${option?.value?:''}"/ ]
})
};
Рад видеть, что вы нашли что-то, что соответствует вашей кодовой базе. Помните, что используя
/"${item?.attribute?:''}"/
, вы изменяетеattribute
, заключив его в двойные кавычки"value"
. Таким образом, в json вы получите"attribute":"\"Type\""
вместо ожидаемого"attribute":"Type"
. Чтобы это исправить, просто оставьтеitem?.attribute ?: ''
вместо/"${item?.attribute?:''}"/
.