我是groovy的新手,我一直面临着理解groovy中each{}
和eachwithindex{}
语句的一些问题。
each
和eachWithIndex
实际上是方法吗?如果是的话,他们采取的论点是什么?
在groovy文档中有这个例子:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" } //prints each index and number
嗯,我看到numbers
是一个数组。上述声明中的num
和idx
是什么? ->
运营商做了什么?
我知道$idx
和$num
打印了值,但是idx
和num
如何自动与数组的索引和内容相关联?这背后的逻辑是什么?请帮忙。
答案 0 :(得分:40)
这些是简单的方法,但它们遵循一个特定的模式 - 它们以Closure
作为最后一个参数。闭包是一种功能,您可以传递并在适用时调用。
例如,方法eachWithIndex可能看起来像这样(粗略地):
void eachWithIndex(Closure operation) {
for (int i = 0; this.hasNext(); i++) {
operation(this.next(), i); // Here closure passed as parameter is being called
}
}
这种方法允许构建通用算法(如项目上的迭代),并通过传递不同的闭包来在运行时更改具体的处理逻辑。
关于参数部分,如上例所示,我们使用两个参数(当前元素和当前索引)调用闭包(operation
)。这意味着eachWithIndex方法不仅要接收任何闭包,而且要接受接受这两个参数的闭包。从语法角度来看,在闭包定义期间定义参数,如下所示:
{ elem, index ->
// logic
}
所以->
用于将闭包定义的参数部分与其逻辑分开。当一个闭包只接受一个参数时,可以省略其参数定义,然后在闭包的作用域内可以访问该参数,名称为it
(第一个参数的隐式名称)。例如:
[1,2,3].each {
println it
}
可以像这样重写:
[1,2,3].each({ elem ->
println elem
})
正如您所看到的,Groovy语言添加了一些语法糖,使这些结构看起来更漂亮。
答案 1 :(得分:11)
each
和eachWithIndex
将所谓的Closure
作为论据。闭包只是一个用{}
括号包裹的Groovy代码。在带有数组的代码中:
def numbers = [ 5, 7, 9, 12 ]
numbers.eachWithIndex{ num, idx -> println "$idx: $num" }
只有一个参数(闭包,或更确切地说:函数),请注意在Groovy中()
括号有时是可选的。 num
和idx
只是闭包(函数)参数的可选别名,当我们只需要一个参数时,这是等价的(it
是第一个闭包参数的隐式名称,非常方便):
def numbers = [ 5, 7, 9, 12 ]
numbers.each {println "$it" }
参考文献:
答案 2 :(得分:0)
通常,如果您使用的是Groovy等函数式编程语言,您可能希望避免使用each
和eachWithIndex
,因为它们鼓励您修改闭包内的状态或执行有侧面的操作的效果。
如果可能,您可能希望使用其他常规收集方法执行操作,例如.collect
或.inject
或findResult
等。
但是,要将这些用于您的问题,即使用索引打印列表元素,您需要在原始集合上使用withIndex
方法,该方法将集合转换为[element]对的集合,索引]
例如,
println(['a', 'b', 'c'].withIndex())
答案 3 :(得分:-2)
EachWithIndex
可以按如下方式使用:
package json
import groovy.json.*
import com.eviware.soapui.support.XmlHolder
def project = testRunner.testCase.testSuite.project
def testCase = testRunner.testCase;
def strArray = new String[200]
//Response for a step you want the json from
def response = context.expand('${Offers#Response#$[\'Data\']}').toString()
def json = new JsonSlurper().parseText(response)
//Value you want to compare with in your array
def offername = project.getPropertyValue("Offername")
log.info(offername)
Boolean flagpresent = false
Boolean flagnotpresent = false
strArray = json.Name
def id = 0;
//To find the offername in the array of offers displayed
strArray.eachWithIndex
{
name, index ->
if("${name}" != offername)
{
flagnotpresent= false;
}
else
{
id = "${index}";
flagpresent = true;
log.info("${index}.${name}")
log.info(id)
}
}