在Drools中获得相似的对象



假设我有一个衬衫类型的对象列表,每个衬衫都有一个颜色属性。是否有办法创建一个规则,只得到相同颜色的衬衫(无论颜色是什么)?

您正在寻找collect函数。(链接到Drools文档,向下滚动一点可以找到"收集"。)顾名思义,它收集符合条件的东西。

让我们假设一个简单的类Shirt有一个字符串color变量。让我们也假设在工作记忆中有各种各样的衬衫实例。

rule "Collect shirts by color"
when
Shirt( $color: color )
$shirts: List() from collect( Shirt( color === $color ) )
then
// $shirts will now contain all shirts of $color
end

此规则将单独考虑每件衬衫,然后收集所有具有相同颜色的其他衬衫。因此,如果你有红色,蓝色和绿色的衬衫,你将至少一次进入右边的单一颜色的$shirts

当然,这里的问题是,您将以每件衬衫为基础触发规则,而不是以每种颜色为基础。所以,如果你有两件红色衬衫,你将用所有红色衬衫触发两次'then'子句(每件红色衬衫触发一次,因为每件红色衬衫将独立满足第一个条件。)

如果你不介意,那么你可以按原样使用它。但是如果你只是想让你的结果每件衬衫颜色触发一次,我们必须更狡猾一点。

为了使颜色成为一等公民,我们需要提取衬衫颜色的不同集合(不是列表!),然后根据需要使用这些来收集我们的列表。这里我使用accumulate函数;您可以在我之前分享的Drools文档的相同链接中阅读更多信息(accumulate直接位于collect之后)

rule "Get shirt colors"
when
// Get all unique shirt colors
$colors: Set() from accumulate( Shirt( $color: color), collectSet( $color ))
// Get one of those colors
$color: String() from $colors
// Find all shirts of that color
$shirts: List() from collect( Shirt( color === $color ) )
then
// $shirts is all shirts of $color
end

在第二条规则中,每种颜色只触发右侧一次,因为我们一开始就将所有可能的颜色提炼成一组独特的颜色。


反之更简单。如果你需要做的只是确认至少有一件衬衫的颜色不同,我们只需要得到所有的颜色,并确认至少有两种不同的颜色。

rule "At least one shirt of a different color"
when
$colors: Set( size > 1 ) from accumulate( 
Shirt( $color: color), 
collectSet( $color )
)
then
// $colors contains more than 1 color, so there's at
// least 1 shirt present that is not the same color
// as the rest
end

最新更新