如何从 JavaScript 的嵌套结构中递归删除所有对象?

问题描述 投票:0回答:1

要求:

  1. 我正在尝试过滤掉所有值为
    ""
    null
    的对象。如果该值为
    ""
    那么我希望该对象从规则数组中删除。
  2. 之后,如果规则数组长度为
    0
    ,则删除规则数组所在的整个对象。
  3. 这应该递归地完成,直到所有值为 null 的对象和空规则数组都被删除。

我尝试过递归方法来解决它,但它没有按预期工作。

const obj = {
  "condition": "OR",
  "rules": [{
      "comparator": "equals",
      "value": "Test1",
      "filterType": "TEXT"
    },
    {
      "comparator": "equals",
      "value": "",
      "filterType": "TEXT"
    },
    {
      "condition": "AND",
      "rules": [{
          "comparator": "equals",
          "value": "Test2",
          "filterType": "TEXT"
        },
        {
          "condition": "OR",
          "rules": [{
            "comparator": "equals",
            "value": "",
            "filterType": "TEXT"
          }]
        },
        {
          "condition": "AND",
          "rules": [{
            "comparator": "equals",
            "value": "Test3",
            "filterType": "TEXT"
          }]
        }
      ]
    },
    {
      "condition": "AND",
      "rules": [{
        "comparator": "equals",
        "value": "",
        "filterType": "TEXT"
      }]
    }
  ]
}



function getValidQueryBuilder(queryBuilder) {
  const queryBuilderObject = queryBuilder;
  if (isQueryBuilderObjectInvalid(queryBuilder)) {
    return null;
  }
  if (Array.isArray(queryBuilderObject.rules)) {
    queryBuilderObject.rules = queryBuilderObject.rules.filter(rule => {
      if (isQueryBuilderObjectInvalid(rule)) {
        return false;
      }
      if (Array.isArray(rule.rules)) {
        rule.rules = filterRules(rule);

        if (rule.rules.length === 0) {
          return false;
        }
        rule.rules.forEach(innerRule => {
          getValidQueryBuilder(innerRule);
        });
      }
      return rule.value !== '' && rule.value !== null;
    });
    if (queryBuilderObject.rules.length === 0) {
      delete queryBuilderObject.rules;
    }
  }
  return queryBuilderObject;
}

function filterRules(rule) {
  return rule.rules.filter(innerRule => {
    return innerRule.value !== null;
  });
}

function isQueryBuilderObjectInvalid(rule) {
  return typeof rule !== 'object' || Object.keys(rule).length === 0;
}


const result = getValidQueryBuilder(obj);
console.log(result);

预期输出:

{
    "condition": "AND",
    "rules": [{
            "comparator": "equals",
            "value": "Test1",
            "filterType": "TEXT"
        },
        {
            "condition": "AND",
            "rules": [{
                    "comparator": "equals",
                    "value": "Test2",
                    "filterType": "TEXT"
                },
                {
                    "condition": "AND",
                    "rules": [{
                        "comparator": "equals",
                        "value": "Test3",
                        "filterType": "TEXT"
                    }]
                }
            ]
        }
    ]
}
javascript typescript recursion query-builder
1个回答
-2
投票

这里应该检查规则是否具有规则或值并将其保存在树中,这将为您提供预期的输出:

const obj={condition:"OR",rules:[{comparator:"equals",value:"Test1",filterType:"TEXT"},{comparator:"equals",value:"",filterType:"TEXT"},{condition:"AND",rules:[{comparator:"equals",value:"Test2",filterType:"TEXT"},{condition:"OR",rules:[{comparator:"equals",value:"",filterType:"TEXT"}]},{condition:"AND",rules:[{comparator:"equals",value:"Test3",filterType:"TEXT"}]}]},{condition:"AND",rules:[{comparator:"equals",value:"",filterType:"TEXT"}]}]};


function traverse(obj) {
  const {rules, ...out} = obj;
  const filtered = rules?.map(traverse).filter(Boolean);
  if(filtered?.length){
    out.rules = filtered;
  }
  if(!obj.value && !out.rules) return;
  return out;
}

const result = traverse(obj);

console.log(result);

© www.soinside.com 2019 - 2024. All rights reserved.