Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

in operator doesn't support key in object or object in array of objects #27

Open
deinspanjer opened this issue May 12, 2017 · 2 comments

Comments

@deinspanjer
Copy link

Currently, "in" supports these cases:
Primitive element in array: {"in":[ "Ringo", ["John", "Paul", "George", "Ringo"] ]}
Substring in string: {"in":["Spring", "Springfield"]}

However, if the array you are testing for containment holds objects, in doesn't work:
{"in": [ {"a": 1}, [ { "a":1 }, { "b":2 } ] ] }
This gives the error Unrecognized operation a

It seems like it could also support testing for the existence of a key in an object:
{"in": [ "a", { "a":1, "b":2 } ] }
Which also gives the same Unrecognized operation a error.

@jwadhams
Copy link
Owner

jwadhams commented May 12, 2017

Yeah, the problem is that all JsonLogic operators are executed depth-first, except if, and, and or.

I did this initially because (a) the original spec was all arithmetic and logic operators with no side effects, so no one cared if it did some work that got discarded and (b) it simplifies the internal code for every operator to assume they're working on primitives.

(a) stopped being true when I introduced add_operation When I couldn't count on operators being side-effect-free, control structures had to be more careful to not execute both consequent paths of an if statement regardless of the conditional.

We could pretty easily patch in to work for objects it gets as data -- this fails because the implementation of in doesn't expect object attributes, not because the parser thinks a is an operator:

jsonLogic = require('./logic.js');
data = {"stuff":{"a":1, "b":2}};
rule = {"in":["b", {"var":"stuff"}]};
jsonLogic.apply(rule, data);

Another improvement might be to increase the rigor of is_logic() to reject more things that are objects but couldn't be logic (e.g., has more than one key) so line 196 halts recursion early, and replace the exception at line 279 to returns the first parameter unmodified like 196 (one key but not a recognized operation).

The nuclear option would be to make every command responsible for parsing its own parameters, which would have the advantage of letting you introduce your own control structures and re-uniting the structures at 35-156 and 213-250. I haven't thought deeply about this yet, but I'll bet it has unpleasant externalities.

@josephdpurcell
Copy link

The functionality described in #116 would enable someone to write their own operation to achieve this, I believe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants