从列表构建动态闭包列表,以便将其传递给Groovy中的OrderBy

时间:2018-01-01 09:33:59

标签: list groovy closures

我正在关注this文章以设置排序顺序。

以上文章的摘录

class Language {
    String name
    boolean dynamic
    String toString() { "name: $name, dynamic: $dynamic" }
}

def languages = [
    new Language(name: 'Groovy', dynamic: true),
    new Language(name: 'Java', dynamic: false),
    new Language(name: 'Clojure', dynamic: true)
]
def list = ['name', 'dynamic']
sh = new GroovyShell()
closure = sh.evaluate("{  }")
def cList = list.collect { closure(it) }
println cList

// We order first on dynamic property and then name property.
def orderByDynamicAndName = new OrderBy([{ it.dynamic }, { it.name }])

在这里,我想从列表中动态传递闭包列表。

比如说,在不同的应用程序/类中,元素大小有一个列表,列表可能会有所不同这是我想要动态闭包列表的主要原因。

def list = ['name', 'dynamic']

从上面的列表中,想要将其生成为闭包列表,并将其作为参数传递给OrderBy类。

//Build closure list. But, not sure how to generate it from above list
def cList = 

def orderByDynamicAndName = new OrderBy(cList)

试图引用this主题,但有些内容无法根据需要生成cList

尝试构建cList,如下所示;得到错误

def list = ['name', 'dynamic']
sh = new GroovyShell()
closure = sh.evaluate("{ fieldName -> \"it\".fieldName }")
def cList = list.collect { closure(it) } 

错误:

  

抛出异常

     

groovy.lang.MissingPropertyException:没有这样的属性:className:java.lang.String

如何过来?

2 个答案:

答案 0 :(得分:2)

class Language {
    String name
    boolean dynamic
    String toString() { "name: $name, dynamic: $dynamic" }
}

def languages = [
    new Language(name: 'Groovy', dynamic: true),
    new Language(name: 'Java', dynamic: false),
    new Language(name: 'Clojure', dynamic: true)
]

def list = ['dynamic', 'name']
def cList = list.collect{ propName-> { target-> target[propName] } }

def orderBy = new OrderBy(cList)
def sortedLanguages = languages.toSorted(orderBy)

println languages
println sortedLanguages

实际上是这个表达式

list.collect{ propName-> { target-> target[propName] } }

将属性名称列表转换为闭包列表

['dynamic', 'name'] => [ { target-> target['dynamic'] }, { target-> target['name'] } ]

target只是闭包中的参数名称。

稍后,当我们调用sort时,将针对排序数组中的对象调用每个闭包{ target-> target[propName] },并且我们的闭包将通过属性名称返回值。

答案 1 :(得分:0)

经过反复试验,下面的代码对我有用,可以创建闭包列表。

def list = ['dynamic', 'name']
def tempClosureString = list.collect { element -> "{it.$element}" }.join(',')
def cList = new GroovyShell().evaluate("[ $tempClosureString ]")

def orderByDynamicAndName = new OrderBy(cList)

如果有更好的选择,我欢迎。