如何使用Groovy中的collect函数通过字段名查找所有对象?

How to use the collect function in Groovy to find all objects by the name of a field?

我知道这个问题很混乱,让我解释一下。我有一个这样的对象

scmStage: {
"execute": true,
"parallel": true,
"integrationPoints": [
    {
        "method": "checkout",
        "checkout": {
            "credentials": {
                "type": "credentialsId",
                "id": "bitB1"
            },
            "type": "GIT",
            "url": "...",
            "branch": "feature",
            "component": true
        }
    },
    {
        "method": "scm",
        "scm": {
            "credentials": {
                "type": "credentialsId",
                "id": "bitB1"
            },
            "type": "GIT",
            "url": "...",
            "branch": "master"
        }
    },
    {
        "method": "scm",
        "scm": {
            "credentials": {
                "type": "credentialsId",
                "id": "bitB1"
            },
            "type": "GIT",
            "url": "...",
            "branch": "dev"
        }
    }
]
}

我需要检查每个积分点,直到找到 属性

"component": true

在这种情况下,它是第一个。如果积分点具有相同的方法(比方说 METHOD_SCM),我会这样做:

integrationPointComponent = (Map) (((List<Map>) scmStage.integrationPoints)?.findAll {
      it.method == Constants.METHOD_SCM
  })?.collect {
      (Map) it.scm
  }?.findAll {
      it.component
  }?.size() == 1

我的集成点与组件 属性 相同,但实际情况是集成点可以具有三个不同的名称(METHOD_SCMMETHOD_CHECKOUTMETHOD_GIT)

我需要做这样的事情

integrationPointComponent = (Map) (((List<Map>) scmStage.integrationPoints)?.findAll {
    (it.method == Constants.METHOD_SCM || it.method == Constants.METHOD_CHECKOUT || it.method == Constants.METHOD_GIT)
    })?.collect {
        (Map) it.scm  <-------PROBLEM
    }?.findAll {
        it.component
    }?.size() == 1

我需要每个方法根据方法在收集函数中写入它的名称,如果它是 METHOD_SCM,那么它应该是 it.scm,如果它是 METHOD_CHECKOUT 那么它应该为 it.checkout,类似于 git。

有什么方法可以一次写完,而不是为每个案例写 3 个不同的案例,比如使用方法 属性 作为集合中的一个字段,像这样:

?.collect {
    (Map) it.[it.method]   or ${it.method} or  something else...need help
}?.findAll {
    it.component
}?.size() == 1

或者问这个问题的另一种方式是,什么是获得组件集成点的最佳方式 属性?

编辑 1:@daggett 我按照@dagget 的建议尝试了第一个变体,如下所示:

(((List<Map>) scmStage.integrationPoints)?.find{
it.method in ['checkout', 'git', 'scm'] && it[it.method]?.component==true })

第一部分:it.method in ['checkout', 'git', 'scm'] 抛出错误:

'ArrayList<String>' cannot contain 'Object'

我通过将 it.method 转换为字符串来解决它,如下所示:

(String)it.method in ['checkout','scm', 'git']

但是第二部分还有一个问题:it[it.method]?.component==true

也就是下面的: No candidates found for method call it[it.method]?.component

但是,有趣的是,它起作用了! 谢谢大佬,给个赞。

def scmStage = new groovy.json.JsonSlurper().parseText(''' {
"execute": true,
"parallel": true,
"integrationPoints": [
    {
        "method": "scm",
        "scm": {
            "credentials": {
                "type": "credentialsId",
                "id": "scm-bitbucket"
            },
            "type": "GIT",
            "url": "...",
            "branch": "master"
        }
    },
    {
        "method": "checkout",
        "checkout": {
            "credentials": {
                "type": "credentialsId",
                "id": "scm-bitbucket"
            },
            "type": "GIT",
            "url": "...",
            "branch": "feature",
            "component": true
        }
    },
    {
        "method": "scm",
        "scm": {
            "credentials": {
                "type": "credentialsId",
                "id": "scm-bitbucket"
            },
            "type": "GIT",
            "url": "...",
            "branch": "dev"
        }
    }
]
}''')


def p = scmStage.integrationPoints.find{ it.method in ['checkout'] && it[it.method]?.component==true }
assert p