How drools to iterate over a list - list

I'm new to Drools6.4.0.FINAL and want to use it to iterate over a list of items and process my business logic
my business data return List ,I want insert it into KieSession
List<MyObject> list = service.queryList(Map<String,Object> param);
kSession.insert(list);
kSession.fireAllRules();
my drl file like this :
import java.util.List;
import xxx.xxx.MyObject;
rule "rule 1"
salience 1
activation-group "ctoc_order_rule"
when
$mo:MyObject(orgunitid_lev1 == 58094);
then
$mo.setBusiness_type_id(201);
$mo.setBusiness_type_name("business201");
update($mo);
end
But this not fire my rules,How can I do to fire a List ? thanks

If you want to match a java.util.List, insert a List and write a pattern List(...).
If you want to match a xxx.xxx.MyObject, insert a MyObject and write a pattern MyObject(...).
If you insert a List and have pattern MyObject(...), it cannot match. It would be possible to match a List and extract the elements (using from), but matching (generic) container classes is somewhat of an anti-pattern. What if you have several kinds of List containing various object?

Related

Merge 2 object lists in java

i have two lists listA and listB of type object
ListA[name=abc, age=34, weight=0, height=0] data collected from excel sheet
ListB[name=null, age=0, weight=70, height=6] data collected from database
Now i want to combine both the lists into a single list
MergedList[name=abc, age=34, weight=70, height=6]
Note: my obj class has more than 15 properties so adding each property one by one using getProperty() will be time-consuming.is there a better way?
Convert them to a Map where the key is the name of the object ( you denoting the elements as name=abc suggests they are name/value pairs ).
Map<String,MyMysteriousObject> converted = list.stream().collect( Collectors.toMap(MyMysteriousObject::getName, Function.identity() ) );
( replace the getName with what ever function you use to get the name of your object )
And then just merge the maps. How to merge maps is described here for example.
While at it, consider replacing the List with Map in your entire code. Will surely save a lot of work elsewhere too.
But if you have to have a list again, just List<MyMysteriousObject> resultList = new ArrayList<>(resultMap);

Using linq to append list to list from select method

I have a collection A of let's say 100 items. From that list I want to perform a where clause which can rule out let's say 20 of items.
Is there a way to use Select clause or something else on items in which I could use external method that returns 2 items.
I would need to end up with 160 objects from the original list.
What I currently have is
public List<A> ToAList(B item)
{
return new List<A> {new A(), new A()};
}
If I make this call
originalList.Where(x => true).Select(y => ToAList(y)).ToList();
I end up having a list of 80 (from pseudo example) two-item A lists instead of a list containing 160 objects A.
I am looking for a way to avoid loops. Just plain Select or AddRange trick that could result in one list.
You can use SelectMany:
originalList.Where(x => true).SelectMany(y => ToAList(y)).ToList();

Search for an item in a text file using UIMA Ruta

I have been trying to search for an item which is there in a text file.
The text file is like
Eg: `
>HEADING
00345
XYZ
MethodName : fdsafk
Date: 23-4-2012
More text and some part containing instances of XYZ`
So I did a dictionary search for XYZ initially and found the positions, but I want only the 1st XYZ and not the rest. There is a property of XYZ that , it will always be between the 5 digit code and the text MethondName .
I am unable to do that.
WORDLIST ZipList = 'Zipcode.txt';
DECLARE Zip;
Document
Document{-> MARKFAST(Zip, ZipList)};
DECLARE Method;
"MethodName" -> Method;
WORDLIST typelist = 'typelist.txt';
DECLARE type;
Document{-> MARKFAST(type, typelist)};
Also how do we use REGEX in UIMA RUTA?
There are many ways to specify this. Here are some examples (not tested):
// just remove the other annotations (assuming type is the one you want)
type{-> UNMARK(type)} ANY{-STARTSWITH(Method)};
// only keep the first one: remove any annotation if there is one somewhere in front of it
// you can also specify this with POSISTION or CURRENTCOUNT, but both are slow
type # #type{-> UNMARK(type)}
// just create a new annotation in between
NUM{REGEXP(".....")} #{-> type} #Method;
There are two options to use regex in UIMA Ruta:
(find) simple regex rules like "[A-Za-z]+" -> Type;
(matches) REGEXP conditions for validating the match of a rule element like
ANY{REGEXP("[A-Za-z]+")-> Type};
Let me know if something is not clear. I will extend the description then.
DISCLAIMER: I am a developer of UIMA Ruta

How to change a node's property based on one of its other properties in Neo4j

I just started using Neo4j server 2.0.1. I am having trouble with the writing a cypher script to change one of the nodes property to something based one of its already defined properties.
So if I created these node's:
CREATE (:Post {uname:'user1', content:'Bought a new pair of pants today', kw:''}),
(:Post {uname:'user2', content:'Catching up on Futurama', kw:''}),
(:Post {uname:'user3', content:'The last episode of Game of Thrones was awesome', kw:''})
I want the script to look at the content property and pick out the word "Bought" and set the kw property to that using a regular expression to pick out word(s) larger then five characters. So, user2's post kw would be "Catching, Futurama" and user3's post kw would be "episode, Thrones, awesome".
Any help would be greatly appreciated.
You could do something like this:
MATCH (p:Post { uname:'user1' })
WHERE p.content =~ "Bought .+"
SET p.kw=filter(w in split(p.content," ") WHERE length(w) > 5)
if you want to do that for all posts, which might not be the fastest operation:
MATCH (p:Post)
WHERE p.content =~ "Bought .+"
SET p.kw=filter(w in split(p.content," ") WHERE length(w) > 5)
split splits a string into a collection of parts, in this case words separated by space
filter filters a collection by a condition behind WHERE, only the elements that fulfill the condition are kept
Probably you'd rather want to create nodes for those keywords and link the post to the keyword nodes.

Search for element list inside list in python

My objective is to search for the word after "IDENTIFIER" in the list. I have input as list which can have list inside list inside list or just list inside list. Basically we have to find how many list inside lists are present and then perform the check.
I have lists inside lists as shown below
[['CLASS', 'class'], ['CLASS', 'animal'], ['LCURLY', '{'], [[['INT', 'int'], ['IDENTIFIER', 'a'], ['SEMICOLON', ';']], [['BOOL', 'bool'], ['IDENTIFIER', 'x'], ['SEMICOLON', ';']]], ['RCURLY', '}']]
I want to search for next element after the word IDENTIFIER. that is i am looking for "a" , and "x". This is case of list inside list inside list. That is two groups of nested list.
But I also have a list as follows:
[['INT', 'int'], ['IDENTIFIER', 'e'], ['SEMICOLON', ';']]
This is case of only list inside list. Now i want to search for word after IDENTIFIER that is "e".
So, Basically all I want to know how to search if there is list inside list and if there is no list inside list then perform a check. All I could think is write a function where i would pass my list and then check if there exist a list inside the list if there is still list then call the function again ( recursively ) and once there is no such list present then perform the check.
Is this the right way to go ahead ? Are there any better suggestions than this .