如何使用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_SCM
、METHOD_CHECKOUT
和 METHOD_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
我知道这个问题很混乱,让我解释一下。我有一个这样的对象
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_SCM
、METHOD_CHECKOUT
和 METHOD_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