TotalTechGeek / json-logic-engine

Construct complex rules with JSON & process them.
MIT License
46 stars 9 forks source link

Matching documents in array #14

Closed Mihailoff closed 1 year ago

Mihailoff commented 1 year ago

There is some operator that iterates over an array.

https://github.com/TotalTechGeek/json-logic-engine/blob/5f1d2b5b039e9add4a505f8a23713ebd0bb6d9c4/test.js#L466

Empty var: '' is confusing, a special character like $this could make it more explicit.

test('some true', () => {
      const answer = logic.run({
        some: [
          [1, 2, 3],
          {
            '>': [
              {
                var: '$this'
              },
              2
            ]
          }
        ]
      })

      expect(answer).toBe(true)
    })

Regarding the nested object, I'd expect something like this:

test('some true', () => {
      const answer = logic.run({
        some: [
          [{ a: 5 }, { a: 1 }],
          {
            '>': [
              {
                var: '$this.a'
              },
              2
            ]
          }
        ]
      })

      expect(answer).toBe(true)
    })

What do you think?

TotalTechGeek commented 1 year ago

Hi @Mihailoff! I appreciate your contributions to the repo!

I actually do agree that being more explicit improves readability in this case, but I'd like to remain as spec-compliant as possible with JSON-Logic.

Thinking through options:

If "$this" was added, would the traversal syntax remain the same?

For example,

If you wanted to access data from an above section,

../../a inside of the some block would let you access the data from what was passed into the function.

Mihailoff commented 1 year ago

Where is the spec? :) https://jsonlogic.com doesn't mention empty var...

../../a

Following the "path" style, should it be then a dot .?


This is my use case, a document with subdocuments. Will this work?

// doc = { items: [ { a: 1 }, { a: 2 } ] }
{ 'some': [
   { 'var': 'items' },
   { '<': [
     { 'var': 'a' }
     10
   ] }
] }
TotalTechGeek commented 1 year ago

Hm, the website fails to mention it there:

But it is implemented in the mainline repo here: https://github.com/jwadhams/json-logic-js/blob/9c805e9ac6a3787e8508e982a079888d3cc295b5/logic.js#L126

And shows up on the website under this section: https://jsonlogic.com/operations.html#all-none-and-some

And is part of the test suite: https://jsonlogic.com/tests.json

[ {"var":""}, 1, 1 ],
[ {"var":null}, 1, 1 ],
[ {"var":[]}, 1, 1 ],

Also yes, your rule there will work perfectly!

import LogicEngine from './logic.js'

const engine = new LogicEngine()

const validate = engine.build({
  some: [
    {
      var: 'items'
    },
    {
      '<': [
        {
          var: 'a'
        },
        10
      ]
    }
  ]
})

console.log(validate({
  items: [
    {
      a: 1
    },
    {
      a: 2
    }
  ]
})) // true

console.log(validate({
  items: [
    {
      a: 11
    },
    {
      a: 12
    }
  ]
})) // false