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.,
[java]
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.
[/java]
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:
[java]Eval.x(java.lang.Object x, java.lang.String expression)[/java]
Its usage is like this:
[java]assert 10 == Eval.x(2, ‘ x * 4 + 2’)[/java]
and I wrote:
[java]
students.sort {Eval.x(it, "x.${sortField}")} // sortField could be student.course?.college?.name
[/java]
In addition to this, groovy.util.Eval has some more useful methods like:
[java]
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’)
[/java]
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’