我们都在初中数学课上学习了集合和维恩图。集合A的哪些元素也是集合B的成员?这个概念也出现在决策逻辑中,你会期望DMN能够处理它。它可以,但它有点复杂,因为从技术上讲,DMN没有集合的概念,即没有重复的无序元素集合。相反,它有列表,有序的集合,可能包括重复项。尽管如此,我们仍然可以在DMN中对集合执行集合操作。这篇文章将向您展示如何操作。
测试单个项目的成员资格时,列表和集合之间没有区别。在决策模型中经常测试某些单个项目是否包含在DMN列表中,并且有多种方法可以做到这一点。例如,假设我们有一个必需附件类型的静态列表,我们想知道该列表中是否包含特定附件。从技术上讲,必需附件类型是一个列表,但它不包含重复值,顺序也无关紧要,因此它实际上是一个集合。我们可以使用下面的DRD测试输入数据附件是否在所需列表中。

假设“所需附件类型”仅包括“附件类型”的五个可能值中的两个,输入数据附件的类型为“附件”,结构如下所示:如下所示。


布尔决策是必需的,可以使用带有listcontains()函数的文字表达式

或in运算符:

您可以在过滤器上使用count():

交集
让我们从交叉点开始。两个集合的交集是属于两者的项目的集合。过滤器
distinctvalues(listA[listcontains(listB,item)])
返回listA中也包含在listB中的项的列表。因此,它是setA和setB交集的有序版本。
为了测试两个集合是否相交,我们可以将count()函数应用于上面的列表,或者我们可以使用some..in..satisfiesoperator。后者实际上更直接:
someiteminlistAsatisfieslistcontains(listB,item)
让我们将其应用于所需的附件类型示例。它略有不同,因为listA和listB的数据类型不同,并且附件可能包含具有相同类型组件的多个项目。

现在输入数据“附件”是“附件”的集合,决策交叉点查找其类型组件位于集合“所需附件类型”中的附件集。在这里,我们可以
省略distinctvalues()函数,因为所有附件都有不同的id值。假设附件有3个项目,其中2个在必需附件类型中:

“交集”使用带有listcontains()的过滤器:


并集
两个集合的并集是属于任何一个集合的项目的集合。FEEL函数
union(listA,listB)
删除重复项,但保留排序。它与
distinctvalues(concatenate(listA,listB))
并且和我们将要得到的一样接近。
在“所需附件类型”示例中,union(附件.类型,所需附件类型)应返回属于任一集合的任何值。


包含
如果setB的所有元素都是setA的成员,我们说setB包含在setA中,即setB是setA的正确子集。为此,我们可以使用every..in..satisfiesoperator测试包含要求。
ifeveryiteminlistBsatsifieslistcontains(listA,item)then...
有时我们可能想测试setB中是否有任何项目不包含在setA中。为此,我们只是否定上面的逻辑:
ifnot(everyiteminlistBsatisfieslistcontains(listA,item))then...
在我们的示例中,我们可以询问“附件”是否包含“所需附件类型”中每种类型的至少一个示例。在我们的例子中,这只是合同和保密协议,两者都包含:


相同
如果setA中的每个项目都在setB中,并且setB中的每个项目都在setA中,则setA和setB是相同的。我们可以测试setB是否包含setA,而setA是否包含setB,但是还有一种更短的方法将union()函数与every..in..satisfies结合使用:
everyiinunion(listA,listB)satisfies(listcontains(listA,i)andlistcontains(listB,i))
在我们的示例中,“附件.类型”与设置的“所需附件类型”不同:


在决策表中集合操作
一个鲜为人知的事实是,决策表条件的广义一元测试格式起源于需要执行类似于此处描述的集合操作。一家工具供应商抱怨说,在他们现有的软件(还不是DMN)中,决策表条件可能是一个复杂的表达式,不限于简单的一元测试所允许的基本比较测试,他们的关键用例类似于上面的那个:附件是否包含所需附件类型列表中的所有项目?这是收容集操作。根据这一要求,DMN任务组创建了广义一元检验,其中任何FEEL表达式都可以在条件单元中使用,将列标题变量替换为“?”字符。当时我看不出它有什么用处,但事实证明它非常有用。(当然,要求它的供应商仍然没有采用DMN。)
在下面的决策表中,?在条件单元格中,代表列标题“所需附件类型”。如果“附件.类型”包含所有“所需附件类型”,则该决策将返回“true”。


DMN是一种非常通用的语言,能够实现看似超出其领域的逻辑。