我试图编写一个迷你递归闭包来解决父子迭代问题。在某个时刻,我需要在递归调用闭包之前检查是否存在其他子节点。我用IF进行检查,但由于某种原因,if返回总是为真。
使用包含的对象更新代码
有一个Json对象,其结构为Parent Children(在下面的代码中称为jsonArray)
[
{
"id": "1",
"name": "No Children" //And yet the if condition is true -> element.children
},
{
"id": "2",
"name": "Does not like Children either"
},
{
"id": "123",
"name": "Some Parent Element",
"children": [
{
"id": "123123",
"name": "NameWhatever"
},
{
"id": "123123123",
"name": "Element with Additional Children",
"children": [
{
"id": "123123123",
"name": "WhateverChildName"
},
{
"id": "12112",
"name": "NameToMap"
}
]
}
]
}
]
还有一个没有ID的ArrayList对象,需要从jsonArray的迭代中检索它们, 这被称为elementsToGetID,我过度简化:
["count": 2741,"value": "NameToMap" ], ["count": 133,"value": "OtherName" ]
两个for循环已经写好了,我正在尝试编写递归闭包以深入了解孩子们
for(int i=0; i<elementsToGetID.size(); i++){
for(int j=0; j<jsonArray.size(); j++){
{ element ->
if(element.name == elementsToGetID[i].value){
elementsToGetID[i]["id"] = element.id
}
if (element.children) {
element.children.each {inst ->
log.info "Element to continue function " +inst
call(inst) //This call fails
}
}
}(jsonArray[j])
}
}
答案 0 :(得分:2)
这是好处。有用。 :)
<强>原因强>
对于递归,闭包必须理解它在调用之前已经定义。
def json = '''
[
{
"id": "1",
"name": "No Children"
},
{
"id": "2",
"name": "Does not like Children either"
},
{
"id": "123",
"name": "Some Parent Element",
"children": [
{
"id": "123123",
"name": "NameWhatever"
},
{
"id": "123123123",
"name": "Element with Additional Children",
"children": [
{
"id": "123123123",
"name": "WhateverChildName"
},
{
"id": "12112",
"name": "NameToMap"
}
]
}
]
}
]
'''
def jsonArray = new groovy.json.JsonSlurper().parseText(json)
def elementsToGetID = [["count": 2741,"value": "NameToMap" ],
["count": 133,"value": "OtherName" ]]
//can be defined here as well
//def closure
for(int i=0; i < elementsToGetID.size(); i++){
for(int j=0; j < jsonArray.size(); j++){
def closure //defined locally
closure = { element ->
if(element.name == elementsToGetID[i].value){
elementsToGetID[i]["id"] = element.id
}
if (element.children) {
element.children.each {inst ->
closure(inst) //This call does not fail anymore
}
}
}
closure(jsonArray[j])
}
}
assert elementsToGetID == [[count:2741, value:'NameToMap', id:'12112'],
[count:133, value:'OtherName']]
答案 1 :(得分:2)
您可以替换dmahapatro's correct answer中的多个for
循环:
for(int i=0; i < elementsToGetID.size(); i++){
for(int j=0; j < jsonArray.size(); j++){
def closure //defined locally
closure = { element ->
if(element.name == elementsToGetID[i].value){
elementsToGetID[i]["id"] = element.id
}
if (element.children) {
element.children.each {inst ->
closure(inst) //This call does not fail anymore
}
}
}
closure(jsonArray[j])
}
}
有了这个,得到相同的结果:
jsonArray.each { a ->
elementsToGetID.find { a.name == it.value }?.id = a.id
if( a.children ) {
{ -> a.children.each( owner ) }()
}
}