javascript - 如何使用 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 。如果匹配,那么我将类型设置为操作 else 条件。
我已经尝试使用 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。您可以采用递归方法。
首先,规则分为“简单”和“复杂”
- 简单的规则有
field
、operator
和value
字段。 - 复杂的规则有一个
rules
属性。
考虑到这一点,将以下逻辑应用于每个规则:
- 转换规则克隆它。
- 如果这是一个复杂的规则,那么:
- 检查它的子规则。如果任何直接子级具有值为
'email'
or的字段'log'
,则将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)
推荐阅读
- python - 绘制与格兰杰因果检验相关的图表
- powerbi - 由于有效身份中缺少角色,无法生成用于访问数据集的嵌入令牌
- eclipse - Cucumber-Maven 使用 Eclipse 设置,不再支持 Source 选项 5。使用 7 或更高版本
- reactjs - 即使我已登录,Auth::check() 也会返回 false。如何修复此错误?
- php - 当它们都具有相同的类名时如何选择特定文本字段的值
- html - 尝试使用 css-grid 但并非所有元素似乎都在正确的位置
- ios - 如何在观看之前准备内容?
- html - Firefox/Chrome 兼容性:具有固定标题和列的 HTML 表格
- python - 资源获取是初始化,在 Python 中
- semaphore - 为什么我们需要单个 cpu 上的信号量?