实现类似规则的场景的理想数据结构是什么



考虑以下场景,其中ID定义的规则需要满足所有条件。

规则ID属性1操作员1值1属性2操作员2值1。。。等等-------------------------------------------------------------------1 x=10 a IN 5,102 x=20 a IN 10,153 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应为

11.3

我想检查是否有比下面的解决方案更简单、更优雅的方法,以及要使用哪种数据结构

数据结构的缺点是什么;以下解决方案中使用的方法?(肯定会有)

Assumptions:

  1. 属性列表目前已固定,但可能会更改
  2. 传入的提要格式是固定的
  3. 不在Java规则实现的线上
  4. 算法答案是可以接受的,Java 7实现是首选

我的解决方案:

  1. 规则集组织为Map<String, List<Criterion>>,其中key是ID,Criterion包含属性、运算符和值作为字段。

  2. 数据被组织为List<Map<String, String>>,其中key是属性(可以是x或a等),value是提要中的实际值。

  3. 对于List<Map<String, String>中的每个条目,请执行以下操作以查找ID

  4. 循环遍历Map<String, List<Criterion>>中的每个条目,并调用以下方法。在返回true的情况下,我记录ID,这是密钥,并打破规则循环&进入下一个数据项。

    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:不是家庭作业;只是一些研究。

我认为您可以使用SmartParam库(http://smartparam.org/)。它是为此类评估而设计的,并且非常通用,因此即使与属性文件以及数据库一起使用,也可以使用if

最新更新