Recursion in groovy (grails)

I am trying to use recursion in groovy to intersect a tree relation. The code below executes one loop, up to childNodes && recurClosure (childNodes), but does not cause the closure to close again. At this point, childNodes had two objects (a list of arrays) of the same type as root.

The code defines recurClosure and calls a list of objects (root). It then iterates through each element and discards the child nodes (using grails dsl for this). If childNodes is not null, it calls the parent method recursively.

Should I break it, or what is wrong?

def parentval def root = Domain.list() def recurClosure recurClosure = {inroot -> inroot.each { returnList << it parentval = it childNodes = Domain.withCriteria { eq('parent', parentval ) } } childNodes && recurClosure(childNodes ) }(root) return returnList 

}

early.

Update: The following exception is specified

  ERROR [2010-06-24 08:20:04,742] [groovy.grails.web.errors.GrailsExceptionResolver] Cannot invoke method call() on null object java.lang.NullPointerException: Cannot invoke method call() on null object at com.bsr.test.DomainService$_closure2_closure7.doCall(com.bsr.test.DomainService:68) at com.bsr.test.DomainService$_closure2.doCall(com.bsr.test.DomainService:58) at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy:45) at com.bsr.test.DomainController$_closure3.doCall(DomainController.groovy) at org.apache.shiro.web.servlet.ShiroFilter.executeChain(ShiroFilter.java:687) at org.apache.shiro.web.servlet.ShiroFilter.doFilterInternal(ShiroFilter.java:616) at org.apache.shiro.web.servlet.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:81) at java.lang.Thread.run(Thread.java:619) 

Update 2: Now try Daniel's suggestion.

 { inroot -> inroot.each { returnList << it parentval = it childNodes = Domain.withCriteria { eq('parent', parentval ) } if(childNodes) call(childNodes) } /*if(childNodes) call(childNodes)*/ }(root) 

In the above implementation, root is an arraylist. An internal closure infers each element from it and recursively calls an anonymous closure. When I moved the β€œcall” inside each closure, it does not call an external anonymous closure, but inroot.each {} itself. So, I get an error

 ERROR [2010-06-24 08:47:46,438] [groovy.grails.web.errors.GrailsExceptionResolver] instance not of expected entity type: java.util.ArrayList is not a: com.bsr.test.Domain 

I see a blog post on what to call closure through 'this' > I will update my discovery .. thanks

Update 3: way to call external closure - owner.call (childNodes)

+4
source share
2 answers

The problem is that when

 recurClosure = { [...] }(root) 

you do not assign a closure to recurClosure , but rather the return value of its call! So, of course, you cannot call closure through recurClosure() ...

Two possible solutions:

Define the closure first, and then call it separately, as air_blob suggested:

 def recurClosure = { [...] } recurClosure(root) 

Use the implicit function call() for recursion. That way you can even work with anonymous closures. IMHO is a very good way to implement recursion in Groovy:

 { inroot -> inroot.each { returnList << it parentval = it childNodes = Domain.withCriteria { eq('parent', parentval ) } } if(childNodes) call(childNodes) }(root) 

Two more comments on your code:

  • You can declare returnList : def returnList = []
  • While childNodes && recurClosure(childNodes ) can do what you need, it’s much more readable to sacrifice another char and describe if ..; -)
  • Would you like to call your closure recursively inside each ?

Another (higher level) comment on your code: if the parents and their children are of the same type ( Domain ), will Domain.list() not return all the children? Is there a need to manually traverse the tree?

+10
source

Are there any exceptions? You tried to use it separately as follows:

 def recurClosure recurClosure = {inroot -> [... stuff ...] } recurClosure(root) 

What exactly do you want to do on this line:

 childNodes && recurClosure(childNodes ) 
+2
source

Source: https://habr.com/ru/post/1313724/


All Articles