如果Groovy Closures中的语句

时间:2014-02-11 09:30:03

标签: groovy closures

我试图编写一个迷你递归闭包来解决父子迭代问题。在某个时刻,我需要在递归调用闭包之前检查是否存在其他子节点。我用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])

    }
}

2 个答案:

答案 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 ) }()
    }
}