Search code examples
drools

drools - get index of item in collection


I have a restaurant app and have a rule where a 20% discount needs to be offered for every 2nd ice-cream.

So,

  • If bill has 2 icecreams, 20% discount on the 2nd icecream
  • If bill has 3 icecreams, still 20% discount on the 2nd icecream
  • If bill has 4 icecreams, 20% discount on the 2nd and 4th icecreams

I have a collection called $bill.items which contains each individual item in the bill.

How can I write this rule in Drools given that there seems to be no way to access the index of an element in a collection.


Solution

  • Just collect them up and apply the discounts on the right-hand-side:

    rule "Discount multiple ice creams"
    when
        $bill : Bill()
        $iceCreams : ArrayList( size > 1 ) from $bill.items
    then
        for (int i = 0; i < $iceCreams.size(); i++) {
            if (i % 2 == 0) {
                // Apply a discount
            }
        }
    end
    

    Or if each bill item is available in working memory, the following can be used on the LHS to collect them:

    $iceCreams : ArrayList( size > 1 )
                 from collect( BillItem(type == "Ice Cream") )
    

    You may need to re-sort the list you have collected, based on each item's index within the bill.

    Although, does the order of the items on a single bill really matter? The order in which items are entered on a bill is a rather unusual basis for a discount. As a customer buying 2 ice creams of differing price, I would ask for the cheapest item first because I will get a bigger discount on the second ice cream added to my bill. Hence why such discounts are usually applied to the N cheapest items. i.e. If 4 ice creams are purchased, then the 2 cheapest are discounted. Also, are ice creams different prices? If each ice cream is the same price, then all you really need to know is how many need to be discounted.