0

I am following this article to set the Order for sorting.

Excerpt from above article

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 }])

Here, I would like to pass the list of closures dynamically from a list.

Say, there is a list and list may vary in element size in different applications / classes. This is main reason I wanted the dynamic closure list.

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

From the above list, want to generate it as list of closure and pass it to OrderBy class as argument.

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

def orderByDynamicAndName = new OrderBy(cList)

Tried to refer this thread, but some how could not generate cList as desired

Tried to build cList as shown below; getting errors

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

Error:

Exception thrown

groovy.lang.MissingPropertyException: No such property: fieldName for class: java.lang.String

How to over come this?

Community
  • 1
  • 1
Rao
  • 20,781
  • 11
  • 57
  • 77

2 Answers2

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

actually this expression

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

converts list of property names to list of closures

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

and target is just a parameter name in the closure.

later, when we call sort, each closure { target-> target[propName] } will be called against an object in a sorting array and our closure returns the value by a property name.

daggett
  • 26,404
  • 3
  • 40
  • 56
0

After trial and error, below code worked for me in order to create the list of closures.

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

def orderByDynamicAndName = new OrderBy(cList)

I welcome if there are better alternatives.

Rao
  • 20,781
  • 11
  • 57
  • 77