feat: Add three new operators for comparing arrays, commonly needed in workflow automation systems.#130
Conversation
…tains_none) Add three new operators for comparing arrays: - contains_all: Check if all elements of array B exist in array A - contains_any: Check if any element of array B exists in array A - contains_none: Check if no elements of array B exist in array A These operators are useful for workflow automation systems where users define conditions like: - "If selected options contain ALL of ['VIP', 'Premium']" - "If tags contain ANY of ['urgent', 'important']" - "If categories contain NONE of ['blocked', 'spam']" Includes comprehensive test cases for each operator.
diegoholiveira
left a comment
There was a problem hiding this comment.
Documentation: before the LICENSE in our README.md, let's a small documentation about those custom operations and a warning stating that those custom operators is not part of the official spec and may or may not be deprecated in the future.
@TotalTechGeek @beeme1mr this may be included in the final spec are you working on?
arrays.go
Outdated
| "github.com/diegoholiveira/jsonlogic/v3/internal/typing" | ||
| ) | ||
|
|
||
| func init() { |
There was a problem hiding this comment.
Let's merge this init into https://github.com/diegoholiveira/jsonlogic/blob/main/operation.go#L98
Like:
/* CUSTOM OPERATORS */
operators["contains_all"] = containsAll
operators["contains_any"] = containsAny
operators["contains_none"] = containsNoneThere was a problem hiding this comment.
Thanks for the review! I've made the requested changes:
-
README.md: Added documentation for custom operators before the LICENSE section, including a warning that these operators are not part of the
official spec and may be deprecated in the future. -
Code structure: Removed
init()fromarrays.goand moved the operator registration tooperation.gowith a/* CUSTOM OPERATORS */comment.
All tests pass. Let me know if you'd like any further changes!
There was a problem hiding this comment.
We might elect to fold this into a Community Extension for set / array querying, and perhaps roll it into the recommended baseline for JSON Logic implementations.
I think right now, for the bottom two, you'd have to combine some every and in like,
{
"some": [
{ "val": "tags" },
{ "in": [{ "val": [] }, ["urgent", "important"]] }
]
}But it's definitely more cumbersome. 😄
I think contains_all would be difficult to recreate in most implementations, as it requires scope traversal to use with every and in, and we haven't quite agreed on that syntax yet in proposals.
all(['admin', 'editor'], in(@, @.^.^.roles))
a.k.a
{
"all": [
["admin", "editor"],
{
"in": [
{"val": []},
{
"val": [ [2], "roles" ]
}
]
}
]
}That works in:
- https://json-logic.github.io/json-logic-engine/
- https://goplasmatic.github.io/datalogic-rs/playground.html
But nowhere else quite right now. And that's def so much more verbose than what's proposed here.
- Add Custom Operators section to README.md before LICENSE - Move operator registration from arrays.go init() to operation.go - Mark custom operators with /* CUSTOM OPERATORS */ comment
Summary
Add three new operators for comparing arrays, commonly needed in workflow automation systems.
New Operators
contains_all{"contains_all": [["a","b","c"], ["a","b"]]}→ truecontains_any{"contains_any": [["a","b"], ["x","a"]]}→ truecontains_none{"contains_none": [["a","b"], ["x","y"]]}→ trueUse Case
I'm building a workflow automation system where users define conditions in the UI:
The current
inoperator only checks if a single value exists in an array. These new operators enable array-to-array comparison.Usage
Changes
Tests
All tests passing:
=== RUN TestContainsAll
--- PASS: TestContainsAll (0.00s)
=== RUN TestContainsAny
--- PASS: TestContainsAny (0.00s)
=== RUN TestContainsNone
--- PASS: TestContainsNone (0.00s)
PASS
Notes
#129