考虑以下场景,其中由ID定义的规则需要满足所有条件。
RULES ID Attribute1 Operator1 Value1 Attribute2 Operator2 Value1 ... And so on ------------------------------------------------------------------- 1 x = 10 a IN 5,10 2 x = 20 a IN 10,15 3 x = 20 a IN 25,20
以上表示if(x=10) & if(a = 5 or a = 10} & ..., then ID = 1
如果格式为[x, a, ...]
10, 5, ... 10, 10, ... 20, 20, ...
那么ID应该是
1 1 3
我希望检查是否有比以下解决方案更简单和更优雅的方式以及要使用的数据结构。
数据结构的缺点是什么?以下解决方案中使用的方法? (确定可能)
Assumptions:
我的解决方案:
规则集的排列方式为Map<String, List<Criterion>>
,其中key为ID,Criterion包含属性,运算符和值为字段。
数据组织为List<Map<String, String>>
,其中key是属性(可以是x或a等),value是Feed中的实际值。
对于List<Map<String, String>
中的每个条目,请执行以下操作以查找ID
循环遍历Map<String, List<Criterion>>
中的每个条目并调用以下方法。如果返回true
,我会记录ID,这是密钥并打破规则循环&amp;继续下一个数据项。
public boolean executeRules(List<Criterion> list,
Map<String, String> dataItem) {
boolean fullMatch = true;
if(CollectionUtils.isNotEmpty(list)){
for(Criterion rule : list) {
switch (rule.getOperator()) {
case EQUAL_TO: //Similar to EQUAL TO
if(!rule.getValue().equals(dataItem.get(rule.getOperand()))){
fullMatch = false;
}
break;
case IN://Similar to IN
List<String> inCriteria = null;
if(rule.getValue() != null) {
inCriteria = Arrays.asList(((String) rule.getValue()).split("\\s*,\\s*"));
if(!inCriteria.contains(dataItem.get(rule.getOperand()))){
fullMatch = false;
}
} else {
fullMatch = false;
}
break;
default:
LOG.error("Invalid Operator: " + rule.getOperator());
fullMatch = false;
break;
}
if(!fullMatch) {
return false;
}
}
} else {
LOG.error("No Rules found");
return false;
}
return true;
}
PS:不是作业;只是一些研究。