Jooq order precedence

36 Views Asked by At

I have a list of conditions which contains

pair<And, a>, <Or, b>, <And, c>, <Or, d>, <And, e>, <And,f>.

I would like to create one condition from it where all are just next to each other on same level without any parentheses.

So:

a OR b AND c OR d AND e AND f.

The list can contain any number of conditions with mixed operators(And, Or).

Currently if I chain it together in Jooq it generates (a OR b) and c.. etc which is not what I want.

1

There are 1 best solutions below

4
Lukas Eder On BEST ANSWER

This is a fun algorithm. Your list is like a sequence of tokens, similar to what a parser would encounter. You could implement something like a recursive descent parser, similar to jOOQ's own parser. This would make sense if you add more operands to your stream, e.g. Not or arithmetic operators, as well as the possibility of nesting operations, etc.

With only two types of operators, it's probably simpler to just loop over your list like this. Assuming these auxiliary types:

enum Op { And, Or }
record Pair(Op op, Condition c) {}

Write this:

List<Pair> list = List.of(
    new Pair(And, condition("a")),
    new Pair(Or, condition("b")),
    new Pair(And, condition("c")),
    new Pair(Or, condition("d")),
    new Pair(And, condition("e")),
    new Pair(And, condition("f"))
);

Condition or = list.get(0).c;

for (int i = 1; i < list.size(); i++) {
    Pair p = list.get(i);
    Condition and = p.c;

    for (int j = i + 1; j < list.size(); j++) {
        Pair q = list.get(j);

        if (q.op == And) {
            and = and.and(q.c);
            i = j;
        }
        else
            break;
    }

    or = or.or(and);
}

System.out.println(or);

This then prints:

(
  (a)
  or (
    (b)
    and (c)
  )
  or (
    (d)
    and (e)
    and (f)
  )
)