Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
463 views
in Technique[技术] by (71.8m points)

drools - Matching a list (of tags) with another and detecting presence of common elements

My requirement is to match tags. In the example, this particular HourConstraint checks the TeacherHour assigned to Hour(23).

Specifically, it checks TeacherHour.attributes["tags"] for the values ["asst_ct","teacher_john_smith"] and detects atleast one match, two in this case (both "asst_ct" and "teacher_john_smith") .

TeacherHour:
  id: 47
  assigned_hour: Null
  attributes:Map<List<String>>
    "tags":["asst_ct","no_strenuous_duties","kinda_boring","teacher_john_smith"]
    "another_attribute":[...]

HourConstraint:
   hour: Hour(23)
   attribute: "tags"
   values_list: ["asst_ct","teacher_john_smith"]

Question: How do I detect the presence (true or false) of common elements between two lists?

Drools Expert has memberOf and contains, but they check a scalar vs a collection, never a collection vs a collection.

I see two potential ways:

  1. introduce a function boolean isIntersecting(list,list) and tell Drools to use that for truth checking
  2. Implement TeacherHour.attributes[] as a string instead of a list and HourConstraint.valueslist as a regular expression that can match that list
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

There are a few options. Most straight forward is to use the Collections class to do that for you:

rule X
when
    $t: TeacherHour( )
    HourConstraint( Collections.disjoint( $t.attributes["tags"], values_list ) == false )
...

If this is something you would use often in your rules, then I recommend wrapping that function in a pluggable operator, supported by Drools. Lets say you name the operator "intersect", you can then write your rules like this:

rule X
when
    $t: TeacherHour( )
    HourConstraint( values_list intersect $t.attributes["tags"] )
...

A third option, is to use "from", but that is less efficient in runtime as it causes iterations on the first list:

rule X
when
    $t: TeacherHour( )
    $tag : String() from $t.attributes["tags"]
    exists( HourConstraint( values_list contains $tag ) )
...

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...