Drools 让相似的物体流口水

Drools 让相似的物体流口水,drools,Drools,假设我有一个衬衫类型中的对象列表,并且每件衬衫都有一个颜色属性。 有没有一种方法可以创建一个规则,该规则只能获得相同颜色的衬衫(无论颜色是什么)?您正在寻找。(链接到Drools文档,向下滚动一点以查找“collect”。)正如其名称所示,它收集符合条件的内容 让我们假设一个简单的类Shirt,包含一个字符串color变量。我们还假设工作内存中有各种各样的shirt实例 rule "Collect shirts by color" when Shirt( $color:

假设我有一个衬衫类型中的对象列表,并且每件衬衫都有一个颜色属性。 有没有一种方法可以创建一个规则,该规则只能获得相同颜色的衬衫(无论颜色是什么)?

您正在寻找。(链接到Drools文档,向下滚动一点以查找“collect”。)正如其名称所示,它收集符合条件的内容

让我们假设一个简单的类
Shirt
,包含一个字符串
color
变量。我们还假设工作内存中有各种各样的shirt实例

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”条款两次(每件红衫军一次,因为每件红衫军将独立满足第一个标准)

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

为了让颜色成为头等公民,我们需要提取衬衫颜色的不同集合(而不是列表!),然后根据需要使用这些集合来收集我们的列表。这里我使用
累积
函数;你可以在我之前分享到Drools文档的同一链接上阅读更多关于这个的内容(
acculate
直接在
collect
之后)

在第二条规则中,每种颜色只触发一次右侧,因为我们首先将所有可能的颜色提取为一组独特的颜色


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

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

只有在阅读了你非常详细的答案后,我才明白我需要回答相反的问题。因为我使用的是Optaplanner,所以我需要一个规则,在衬衫颜色不一样的情况下,给结果打一个负数。这更容易——我添加了一个负数示例。
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