Groovy 使用gstring访问列表属性元素

Groovy 使用gstring访问列表属性元素,groovy,Groovy,使用gstring可以访问对象的属性,包括嵌套属性。但是如何访问列表属性中的第n个元素呢 class-Foo{ 列表元素 } 分类栏{ 字符串版本 } 我需要使用GString访问Foo.elements对象中特定索引的version属性。 尝试下面的代码但没有成功 def property = "elements[0].version" fooObject."$property" fails to identify the property 因此,我认为有三种方法可以解决这个问题,这取决于

使用gstring可以访问对象的属性,包括嵌套属性。但是如何访问列表属性中的第n个元素呢

class-Foo{
列表元素
}
分类栏{
字符串版本
}
我需要使用GString访问Foo.elements对象中特定索引的version属性。 尝试下面的代码但没有成功

def property = "elements[0].version"
fooObject."$property" fails to identify the property

因此,我认为有三种方法可以解决这个问题,这取决于允许多大的灵活性

class Foo {
   List<Bar> elements
}
class Bar {
  String version
}
  • 如果您可以这样做:

    println fooObject."elements"[1]."version"
    
  • 否则,将所有内容放入字符串中,然后插入:

    println "${fooObject.elements[1].version}"
    
  • 最终,如果上述两项都不适合你:

    def property='elements[1].version'
    def expr = 'fooObject.' + property
    println Eval.me('fooObject', fooObject, expr)
    
  • 最后一个选项将
    fooObject
    作为
    fooObject
    提供给正在求值的表达式,并对表达式求值。

    理想情况下,它可以是:

    def prop1 = "elements"
    def prop2 = "version"
    
    fooObject."$prop1"[0]."$prop2"
    
    冗长而通用的一种方法是使用
    inject

    class Foo {
       List<Bar> elements
    }
    class Bar {
      String version
    }
    
    def fooObject = new Foo(elements: [new Bar(version: '1'), 
                                       new Bar(version: '2'), 
                                       new Bar(version: '3')])
    
    def fetchVersion(property, fooObject) {
        property.tokenize(/./).inject(fooObject) {obj, elem -> 
            if(elem.contains(/[/)){
                def var = elem.tokenize(/[]/)
                obj?."${var[0]}".getAt("${var[1]}".toInteger()) 
            } else {
                obj?."$elem" 
            }
        }
    }
    
    assert fetchVersion("elements[0].version", fooObject) == '1'
    assert fetchVersion("elements[1].version", fooObject) == '2'
    assert fetchVersion("elements[2].version", fooObject) == '3'
    assert fetchVersion("elements[7].version", fooObject) == null
    
    class-Foo{
    列表元素
    }
    分类栏{
    字符串版本
    }
    def fooObject=new Foo(元素:[新条(版本:“1”),
    新条(版本:“2”),
    新栏(版本:“3’)])
    def fetchVersion(属性、对象){
    property.tokenize(/。/).inject(fooObject){obj,elem->
    if(元素包含(/[/)){
    def var=elem.tokenize(/[]/)
    obj?“${var[0]}”.getAt(“${var[1]}”.toInteger())
    }否则{
    obj?“$elem”
    }
    }
    }
    断言fetchVersion(“元素[0].version”,fooObject)==“1”
    断言fetchVersion(“元素[1]。版本”,fooObject)==“2”
    断言fetchVersion(“元素[2].version”,fooObject)==“3”
    断言fetchVersion(“元素[7].version”,fooObject)==null
    
    eval的常见警告适用,运行未知代码可能会导致问题;-)是的,这就是为什么它被排在第三位:)eval在我的场景中工作得非常好。它用于测试代码。eval.Thnx也很好。
    class Foo {
       List<Bar> elements
    }
    class Bar {
      String version
    }
    
    def fooObject = new Foo(elements: [new Bar(version: '1'), 
                                       new Bar(version: '2'), 
                                       new Bar(version: '3')])
    
    def fetchVersion(property, fooObject) {
        property.tokenize(/./).inject(fooObject) {obj, elem -> 
            if(elem.contains(/[/)){
                def var = elem.tokenize(/[]/)
                obj?."${var[0]}".getAt("${var[1]}".toInteger()) 
            } else {
                obj?."$elem" 
            }
        }
    }
    
    assert fetchVersion("elements[0].version", fooObject) == '1'
    assert fetchVersion("elements[1].version", fooObject) == '2'
    assert fetchVersion("elements[2].version", fooObject) == '3'
    assert fetchVersion("elements[7].version", fooObject) == null