代码之家  ›  专栏  ›  技术社区  ›  Nidhin Kumar

如何使用lodash更新对象的嵌套数组

  •  1
  • Nidhin Kumar  · 技术社区  · 4 年前

    我有一个嵌套的对象数组,如下面的结构。我想循环到每个对象,并检查特定字段是否与条件或不,如果它匹配然后更新那个特定的对象。

    结构

    {
      "condition": "and",
      "rules": [
        {
          "condition": "and",
          "rules": [
            {
              "field": "deviceName",
              "operator": "=",
              "value": "device01"
            },
            {
              "field": "temperature",
              "operator": ">",
              "value": 30
            },
            {
              "field": "mail",
              "operator": "to",
              "value": "edison@gmail.com"
            }
          ]
        },
        {
          "condition": "and",
          "rules": [
            {
              "field": "deviceName",
              "operator": "=",
              "value": "device02"
            },
            {
              "field": "voltage",
              "operator": "=",
              "value": 200
            },
            {
              "field": "log",
              "operator": "to",
              "value": "edison@gmail.com"
            },
            {
              "condition": "and",
              "rules": [
                {
                  "field": "deviceName",
                  "operator": "=",
                  "value": "device04"
                },
                {
                  "field": "voltage",
                  "operator": "=",
                  "value": 200
                },
                {
                  "field": "mail",
                  "operator": "to",
                  "value": "edison@gmail.com"
                }
              ]
            }
          ]
        }
      ]
    }
    

    我试过用地图来做,但它只在第一层起作用。假设对象有嵌套数组,我无法过滤它。

      const queryDetail = this.query.rules.map((query: any) => {
        const temp: any = {
          condition: {
            ...query
          }
        };
        if (query.field === 'mail' || query.field === 'log') {
          temp.type = 'action';
        } else {
          temp.type = 'condition';
        }
        return temp;
      });
    
      const updatedQuery = {
        condition: this.query.condition,
        rules: queryDetail
      };
    
    0 回复  |  直到 4 年前
        1
  •  1
  •   VLAZ Sohail Arif    4 年前

    你不需要洛达什。你可以采用递归的方法。

    首先,规则分为“简单”和“复杂”

    • field , operator ,和 value
    • 复杂的规则有一个 rules

    记住这一点,对每个规则应用以下逻辑:

    1. 转换规则克隆它。
    2. 如果这是一个复杂的规则,那么:
      • 检查其子规则。如果任何直系子项有值的字段 'email' 'log' ,然后设置 type 当前复杂规则的 'action' . 否则设置为 'condition' . 即使子规则很复杂,这也可以工作,因为它们没有 属性,因此将被视为与筛选器不匹配的简单规则。
      • 对所有子规则应用相同的逻辑。

    const data = { "condition": "and", "rules": [{ "condition": "and", "rules": [{ "field": "deviceName", "operator": "=", "value": "device01" }, { "field": "temperature", "operator": ">", "value": 30 }, { "field": "mail", "operator": "to", "value": "edison@gmail.com" } ] }, { "condition": "and", "rules": [{ "field": "deviceName", "operator": "=", "value": "device02" }, { "field": "voltage", "operator": "=", "value": 200 }, { "field": "log", "operator": "to", "value": "edison@gmail.com" }, { "condition": "and", "rules": [{ "field": "deviceName", "operator": "=", "value": "device04" }, { "field": "voltage", "operator": "=", "value": 200 }, { "field": "mail", "operator": "to", "value": "edison@gmail.com" } ] } ] } ] }
    
    
    function convertRule(obj) {
      //clone the rule
      const result = {...obj};
      const isComplexRule = "rules" in obj;
    
      if (isComplexRule) {
        //check sub-rules
        const isActionRule = obj.rules.some(checkSimpleRule);
        
        //set the appropriate action
        if (isActionRule) {
          result.type = 'action';
        } else {
          result.type = 'condition';
        }
        
        //re-run the same logic on each sub-rule recursively
        result.rules = result.rules.map(convertRule)
      }
    
      //return the cloned object
      return result;
    }
    
    function checkSimpleRule(rule) {
      return rule.field === 'mail' || rule.field === 'log'
    }
    const queryDetail = convertRule(data)
    
    console.log(queryDetail)