0

I've got a question if I'm somehow able to make this code working like this:

If it matches the first predicate: (it.controller == controllerName && it.actions.contains(actionName)), it finds only those, which match this predicate and it doesn't find from those underneath.

If it doesn't find anything from first predicate, then it goes to second one and finds all which match second predicate, but don't match the third one.

 ArrayList rule = rules.findAll {
            (it.controller == controllerName && it.actions.contains(actionName)) 
            ||
            (it.controller == controllerName && it.actions.contains("*")) 
            ||
            (it.controller == "*" && it.actions.contains("*"))
}
Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
funnyguy
  • 107
  • 1
  • 6

2 Answers2

0

Use findFirst() instead, here's are some good references: https://www.baeldung.com/java-stream-findfirst-vs-findany and Find first element by predicate

SergeyB
  • 9,478
  • 4
  • 33
  • 47
  • Groovy's version of findFirst() is called find: https://docs.groovy-lang.org/latest/html/groovy-jdk/java/util/Collection.html#find(groovy.lang.Closure) – h8red Aug 09 '22 at 12:24
-1

If i understood the question correctly, this should work:

def filterFirst(List list, List<Closure> filters) {
        return filters
                .collect { list.findAll(it) }
                .find { it.size() != 0 }
}

Then, just do

filterFirst(rules, [
        { it.controller == controllerName && it.actions.contains(actionName) },
        { it.controller == controllerName && it.actions.contains("*") },
        { it.controller == "*" && it.actions.contains("*") }
])
h8red
  • 713
  • 4
  • 17
  • `.collect` is going to visit every element in `filters`. Would it be better to use something like `find` to find the first one that matches and then jump ship so the rest don't have to be visited? – Jeff Scott Brown Aug 09 '22 at 14:29