2

I'm using this query component in one of my projects so that users can construct a query.

I'm having difficulty parsing it into an actual example query, for example for this object outputted by the component:

const queryParams = {
  "rules": [
    {
      "rules": [
        {
          "field": "firstName",
          "value": "John",
          "operator": "="
        },
        {
          "field": "lastName",
          "value": "Doe",
          "operator": "="
        }
      ],
      "combinator": "and"
    },
    {
      "rules": [
        {
          "field": "age",
          "value": "20",
          "operator": "="
        },
        {
          "field": "address",
          "value": "London",
          "operator": "="
        }
      ],
      "combinator": "and"
    }
  ],
  "combinator": "and"
}

I need to create a function that would output a more user-friendly readable output as such:

((FirstName = John AND LastName = Doe) AND (AGE = 20 AND Address = London))

I've given it a go but the difficulty I'm finding is that:

  • The object could theoretically be infinitely nested, I never know how nested it is. Is the only way to do this with recursion? Or are there easier ways

  • The rules and groups can be in the same object

The way I'm currently trying will not work dynamically, so any help or guidance would be greatly appreciated.

Thanks

3
  • can you share how you are currently trying to do it? Commented Feb 8, 2019 at 10:49
  • "object could theoretically be infinitely nested" - using for loop should overcome this issue, did you try any recursions? Share your code Commented Feb 8, 2019 at 10:52
  • You can always use a loop and a stack (LIFO) structure to simulate recursion if you decide to go that way. This (non-JS) explanation is pretty straightforward: refactoring.com/catalog/replaceRecursionWithIteration.html ... (although if you want to get into that wacky recursion stuff, this seems like a great JS tutorial: javascript.info/recursion) Commented Feb 8, 2019 at 10:59

1 Answer 1

3

You could take a recursive approach and build either a rules set or a final comparison.

It works by checking the rules property:

  • If given, then the rules are mapped with a recursive call of the function.

    The result of this call is joined with an upper case combinator property and wrapped into a wanted spaced string with parenthesis.

  • If not, then take a new string with field, operator and value property.

function combine(object) {
    return 'rules' in object
        ? `(${object.rules.map(combine).join(` ${object.combinator.toUpperCase()} `)})`
        : `${object.field} ${object.operator} ${object.value}`;
}

var data = { rules: [{ rules: [{ field: "firstName", value: "John", operator: "=" }, { field: "lastName", value: "Doe", operator: "=" }], combinator: "and" }, { rules: [{ field: "age", value: "20", operator: "=" }, { field: "address", value: "London", operator: "=" }], combinator: "and" }], combinator: "and" },
    result = combine(data);

console.log(result);

Sign up to request clarification or add additional context in comments.

4 Comments

Really nice approach, but it would be better with an explanation. ;)
This is really a dump component, its missing the field type :) so we could identify if the field is string, int etc
@Alen.Toma, i think it's just to visualise to the user in a simplified style what's happening.
Correct @NinaScholz - Thank you for the solution this is great

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.