首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >与复杂对象匹配嵌套列表的DROOLS模式

与复杂对象匹配嵌套列表的DROOLS模式
EN

Stack Overflow用户
提问于 2014-12-06 00:18:33
回答 2查看 7.6K关注 0票数 4

我在挣扎于流口水中的模式匹配例程,它遍历复杂嵌套对象的列表。

我有一个POJO结构,如下所示:

代码语言:javascript
运行
复制
class MyFact {
    private List<A> listOfA;
    public List<A> getListOfA() { return listOfA; }
}

class A {
    private List<B> listOfB;
    private String stringField;
    public List<B> getListOfB() { return listOfB; }
    public String getStringField() { return stringField; }
}

class B {
    private String otherStringField;
    public String getOtherStringField() { return otherStringField; }
}

我试图找到正确的语法来收集所有类型为“A”的对象,这些对象与一组条件相匹配,其中还包括包含在“A‘s listOfB”中的对象中的匹配字段。

我认为规则应该是这样的,但是当它在collect( ... )中时,我不会编译它。

代码语言:javascript
运行
复制
import java.util.ArrayList;
rule "Tricky Syntax"
when
    $myFact: MyFact()
    $filteredListOfA: ArrayList( size > 0 ) from collect ( 
        A( stringField == "something", $listOfB: listOfB ) from $myFact.listOfA
        B( otherStringField == "somethingElse" ) from $listOfB
    ) 
then
   // Do something neat with $filteredListOfA
end

我知道它可以用迭代匹配的方式编写,但是如果有匹配的话,我只想激发一次操作,并且有一个A的列表。谢谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-06 06:40:44

这是不可能的,因为在收集CE中不可能有多种模式。(你的意思是收取A或B的,还是两者兼收?)您可以轻松地将其更改为“积累”,这使您完全可以控制所累积的内容:

代码语言:javascript
运行
复制
$myFact: MyFact()
$filteredListOfA: List( size > 0 ) from accumulate ( 
    $a: A( stringField == "something", $listOfB: listOfB ) from $myFact.listOfA
    and
    B( otherStringField == "somethingElse" ) from $listOfB;
    collectList( $a )
) 

后来的

如果当listOfA中的元素不止一次被选中时,list元素应该只出现一次,那么只需使用SetcollectSet

票数 8
EN

Stack Overflow用户

发布于 2014-12-08 15:19:00

使用collectSet()而不是collectList()修复语法和删除A的重复项的一些细微更改

代码语言:javascript
运行
复制
import java.util.Set;
rule "Tricky Syntax"
when
    $myFact: MyFact()
    $filteredListOfA: Set( size > 0 ) from accumulate ( 
        $a: A( stringField == "something", $listOfB: listOfB ) from $myFact.listOfA
        and
        B( otherStringField == "somethingElse" ) from $listOfB;
        collectSet( $a )
    )
then
    // Do something with the $filteredListOfA Set
end

感谢laune指出了一个口角在正确的方向!

另外,值得注意的是,使用collectSet()和collectList()并不一定会保留匹配顺序(由于DROOLs行为)。下面是另一种解决方案,它保留操作的匹配顺序(如果这很重要)。

代码语言:javascript
运行
复制
import java.util.Set;
import java.util.LinkedHashSet;
rule "Tricky Syntax"
when
    $myFact: MyFact()
    $filteredListOfA: Set( size > 0 ) from accumulate ( 
        $a: A( stringField == "something", $listOfB: listOfB ) from $myFact.listOfA
        and
        B( otherStringField == "somethingElse" ) from $listOfB,
        init( Set set = new LinkedHashSet(); ),
        action( set.add( $a ); ),
        result( set )
    )
then
    // Do something with the $filteredListOfA Set
end
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27326773

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档