0

I have a query object for which filter looks like -

"filter": {
    "type": "and",
    "fields": [
        {
            "type": "selector",
            "dimension": "loyalty parent attribute",
            "value": "Most Active Communicator"
        },
        {
            "type": "and",
            "fields": [
                {
                    "type": "and",
                    "fields": []
                },
                {
                    "type": "and",
                    "fields": [
                        {
                            "type": "and",
                            "fields": [
                                {
                                    "type": "not",
                                    "field": {
                                        "type": "in",
                                        "dimension": "corporation",
                                        "values": [
                                            null
                                        ]
                                    }
                                }
                            ]
                        }
                    ]
                }
            ]
        }
    ]
}

As we can see this JSON can very quickly take a very complex form with a few filters. But this is system driven so I can hardly do anything about it. Due to a certain operation, an empty array called fields appears as we can see in the third and operation. Currently, I have written a very hardcoded way to find those empty fields arrays and remove such items. Looking more a more robust way to do this.

2
  • Any empty array or just ones called "fields"? Commented Dec 8, 2020 at 7:46
  • empty array called fields Commented Dec 8, 2020 at 7:47

2 Answers 2

2

This recursively removes empty array fields.

const query = {
  filter: {
    type: "and",
    fields: [
      {
        type: "selector",
        dimension: "loyalty parent attribute",
        value: "Most Active Communicator",
      },
      {
        type: "and",
        fields: [
          {
            type: "and",
            fields: [],
          },
          {
            type: "and",
            fields: [
              {
                type: "and",
                fields: [
                  {
                    type: "not",
                    field: {
                      type: "in",
                      dimension: "corporation",
                      values: [null],
                    },
                  },
                ],
              },
            ],
          },
        ],
      },
    ],
  },
};

function cleanFields(fields){
  return fields.filter(field => {

    if(field.fields){
      // If the field we are currently comparing has nested fields
      // clean those up first before we decide whether or not to keep it
      field.fields = cleanFields(field.fields);
      return field.fields.length > 0;
    }

    return true;
  });
}

const cleaned = cleanFields(query.filter.fields);

console.log(JSON.stringify(cleaned, null, 2))

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

Comments

0

Here is a simple solution using object-scan

// const objectScan = require('object-scan');

const data = { filter: { type: 'and', fields: [{ type: 'selector', dimension: 'loyalty parent attribute', value: 'Most Active Communicator' }, { type: 'and', fields: [{ type: 'and', fields: [] }, { type: 'and', fields: [{ type: 'and', fields: [{ type: 'not', field: { type: 'in', dimension: 'corporation', values: [null] } }] }] }] }] } };

const modify = (obj) => objectScan(['**.fields'], {
  rtn: 'count',
  filterFn: ({ value, gparent, gproperty }) => {
    if (Array.isArray(value) && value.length === 0) {
      delete gparent.splice(gproperty, 1);
      return true;
    }
    return false;
  }
})(obj);

console.log(modify(data)); // returns number of deletions
// => 1
console.log(data);
// => { filter: { type: 'and', fields: [ { type: 'selector', dimension: 'loyalty parent attribute', value: 'Most Active Communicator' }, { type: 'and', fields: [ { type: 'and', fields: [ { type: 'and', fields: [ { type: 'not', field: { type: 'in', dimension: 'corporation', values: [ null ] } } ] } ] } ] } ] } }
.as-console-wrapper {max-height: 100% !important; top: 0}
<script src="https://bundle.run/[email protected]"></script>

Disclaimer: I'm the author of object-scan

Comments

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.