Evaluating Expressions with groovy.util.Eval
A few days ago I faced a problem of evaluating dynamic expressions on domain objects. The scenario was that, depending upon the user input, I needed to sort a list of objects on some properties, which were nested deep in the object, e.g.,
student.course?.college?.name // if a user chose to sort students by college name student.course.teacher.name // if a user chose to sort students by teacher name.
Using if, else could not have been an elegant solution, considering that there were many more fields to be sorted upon. This is when groovy.util.Eval class came to my notice. I found a useful function there:
Eval.x(java.lang.Object x, java.lang.String expression)
Its usage is like this:
assert 10 == Eval.x(2, ' x * 4 + 2')
and I wrote:
students.sort {Eval.x(it, "x.${sortField}")} // sortField could be student.course?.college?.name
In addition to this, groovy.util.Eval has some more useful methods like:
assert 10 == Eval.me(' 2 * 4 + 2') assert 10 == Eval.xyz(2, 4, 2, ' x * y + z') assert 10 == Eval.xy(2, 4, ' x * y + 2')
Hope this helps.
Imran Mir
imran[@]intelligrape.com
I now see what’s wrong with my previous comment, sorry for the false alarm.
Cheers,
Igor Sinev
Hi!
Am I missing something or just
students.sort { it.”${sortField}” }
would do the trick?
This example worked for me:
def list = [new B(x: 1, y: 20), new B(x: 10, y: 1)]
for (s in [‘x’, ‘y’]) {
println list.sort { it.”${s}” }
}
@groovy.transform.Canonical
class B {
int x
int y
}
Cheers,
Igor Sinev
Thanks for sharing Imran
I used it once for using a string as a Map.
def myMap = Eval.me(“[key1:val1,key2:val2]”)
assert myMap.key1 == ‘val1′
assert myMap.key2 == ‘val2′