我在挣扎于流口水中的模式匹配例程,它遍历复杂嵌套对象的列表。
我有一个POJO结构,如下所示:
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( ... )中时,我不会编译它。
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的列表。谢谢!
发布于 2014-12-06 06:40:44
这是不可能的,因为在收集CE中不可能有多种模式。(你的意思是收取A或B的,还是两者兼收?)您可以轻松地将其更改为“积累”,这使您完全可以控制所累积的内容:
$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元素应该只出现一次,那么只需使用Set和collectSet。
发布于 2014-12-08 15:19:00
使用collectSet()而不是collectList()修复语法和删除A的重复项的一些细微更改
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行为)。下面是另一种解决方案,它保留操作的匹配顺序(如果这很重要)。
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
endhttps://stackoverflow.com/questions/27326773
复制相似问题