繁体   English   中英

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

[英]How to update the nested array of object using lodash

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

结构

{
  "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"
            }
          ]
        }
      ]
    }
  ]
}

在上面的结构中,我正在检查每个规则 [] 并检查该字段是否具有值 email 或 log 。如果匹配,则我将类型设置为操作其他条件。

我已经尝试过 map 来做到这一点,但它只能在第一级工作。 假设如果对象具有嵌套数组,我将无法对其进行过滤。

  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
  };

为此,您不需要 Lodash。 您可以采用递归方法。

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

  • 简单规则有fieldoperatorvalue字段。
  • 复杂规则有一个rules属性。

考虑到这一点,将以下逻辑应用于每个规则:

  1. 转换规则克隆它。
  2. 如果这是一个复杂的规则,那么:
    • 检查其子规则。 如果任何直接子级具有值为'email''log'type ,则将当前复杂规则的type设置为'action' 否则将其设置为'condition' 即使子规则很复杂,这也会起作用,因为它们没有field属性,因此将被视为与过滤器不匹配的简单规则一样。
    • 对所有子规则应用相同的逻辑。

 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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM