16 July 2011

Subtract a list of numbers from another one

Valid since: op4j 1.1

Given two lists: one of ordered books and another of sent ones, subtract the sent books from the ordered ones and obtain the not yet sent. Notice that, if more books than ordered have been sent, the subtraction will be negative and you have to set those ones to 0 (we are not worried about the books we get for free).

Our first List<Integer> list variable contains the ordered books:
List<Integer> orderedBooks = new ArrayList<Integer>();
orderedBooks.add(Integer.valueOf(15)); // Ordered units of book A
orderedBooks.add(Integer.valueOf(50)); // Ordered units of book B
orderedBooks.add(Integer.valueOf(23)); // Ordered units of book C
orderedBooks.add(Integer.valueOf(150)); // Ordered units of book D
orderedBooks.add(Integer.valueOf(3)); // Ordered units of book E
orderedBooks.add(Integer.valueOf(98)); // Ordered units of book F
orderedBooks.add(Integer.valueOf(300)); // Ordered units of book G
orderedBooks.add(Integer.valueOf(7)); // Ordered units of book H
Our second List<Integer> list variable contains the sent books:
List<Integer> sentBooks = new ArrayList<Integer>();
sentBooks.add(Integer.valueOf(5)); // Sent units of book A
sentBooks.add(Integer.valueOf(56)); // Sent units of book B
sentBooks.add(Integer.valueOf(23)); // Sent units of book C
sentBooks.add(Integer.valueOf(134)); // Sent units of book D
sentBooks.add(Integer.valueOf(13)); // Sent units of book E
sentBooks.add(Integer.valueOf(98)); // Sent units of book F
sentBooks.add(Integer.valueOf(345)); // Sent units of book G
sentBooks.add(Integer.valueOf(87)); // Sent units of book H
We want to:
  1. Subtract sent books from ordered ones so that we get the not sent ones
  2. Replace those negative results in the previous list by 0 as we just want to know how many books we have not yet received
  3. Add up all the pending units of each book to obtain the total number of not yet sent books

1. Subtract sent from ordered, replace negative units by 0 and add up the result.
op4j-ognl functions involved:
  • FnOgnl.i(final String ognlExpression, final Object... optionalParameters): executes an OGNL expression returning an Integer
  • FnOgnl.bool(final String ognlExpression, final Object... optionalParameters): executes an OGNL expression returning a Boolean

op4j functions involved:
  • FnInteger.sum(): sums up all the items in the iterable target

Let's see it coded with op4j:
Integer pendingBooks = Op.on(orderedBooks).forEach().exec(FnOgnl.i("#target - #param[0].get(#index)", sentBooks))
.execIfTrue(FnOgnl.bool("#target < 0"), FnOgnl.i("#param[0]", Integer.valueOf(0))).endFor() .exec(FnInteger.sum()).get();