I've been trying to learn Groovy lately and I tried to solve a problem which involves designing a routine that will calculate the average Product price per Group.
I have the following data:
// contains information about [Product, Group, Cost]
products = [
["A", "G1", 20.1],
["B", "G2", 98.4],
["C", "G1", 49.7],
["D", "G3", 35.8],
["E", "G3", 105.5],
["F", "G1", 55.2],
["G", "G1", 12.7],
["H", "G3", 88.6],
["I", "G1", 5.2],
["J", "G2", 72.4]
]
// contains information about Category classification based on product Cost
// [Category, Cost range from (inclusive), Cost range to (exclusive)]
// i.e. if a Product has Cost between 0 and 25, it belongs to category C1
category = [
["C3", 50, 75],
["C4", 75, 100],
["C2", 25, 50],
["C5", 100, null],
["C1", 0, 25]
]
// contains information about margins for each product Category
// [Category, Margin (either percentage or absolute value)]
margins = [
"C1" : "20%",
"C2" : "30%",
"C3" : "0.4",
"C4" : "50%",
"C5" : "0.6"]
What I tried so far is the following (I mixed some Java here):
def calculateResult() {
def group1 = []
def group2 = []
def group3 = []
def pricePerGroupMap = [:]
category.each { cat ->
String catDesc = cat[0]
BigDecimal min = cat[1]
BigDecimal max = cat[2]
if (max == null) {
max = 9999.9;
}
products.each { product ->
BigDecimal currProductPrice = BigDecimal.valueOf(product[2])
if (currProductPrice.compareTo(min) >= 0 && currProductPrice.compareTo(max) <= 0) {
String selectedMarginAsString = margins.getAt(catDesc);
BigDecimal selMargin = 0.0;
if (selectedMarginAsString.endsWith("%")) {
selMargin = new BigDecimal(selectedMarginAsString.trim().replace("%", "")).divide(BigDecimal.valueOf(100));
} else {
selMargin = new BigDecimal(selectedMarginAsString);
}
if (product[1].equals("G1")) {
group1.add(product[2] * (1 + selMargin))
} else if (product[1].equals("G2")) {
group2.add(product[2] * (1 + selMargin))
} else if (product[1].equals("G3")) {
group3.add(product[2] * (1 + selMargin))
}
}
}
}
pricePerGroupMap["G1"] = group1.sum() / group1.size()
pricePerGroupMap["G2"] = group2.sum()/ group2.size()
pricePerGroupMap["G3"] = group3.sum()/ group3.size()
print pricePerGroupMap
}
I am sure there are better ways to optimize this algorithm taking advantage of closures.