1
\$\begingroup\$

I have a invoiceList which is a List<Map<String:String>> and am trying to find out if all the invoices have same SENDER_COUNTRY and CLIENT_COUNTRY or not. If not, it will add the message to a JSON array.

[
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617151,SENDER_COUNTRY:USA, CLIENT_COUNTRY:USA]
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617152,SENDER_COUNTRY:CAD, CLIENT_COUNTRY:MEX]
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617153,SENDER_COUNTRY:CAD, CLIENT_COUNTRY:MEX]
]

JSONArray jsonArray = new JSONArray();
def senderCountry = invoiceList[0]['SENDER_COUNTRY']
def clientCountry  = invoiceList[0]['CLIENT_COUNTRY']
invoiceList.each{ it ->
if(it['SENDER_COUNTRY'] != senderCountry)
  jsonArray.add((new JSONObject()).put("SENDER_COUNTRY","Multiple sender Countries Associated"));
 if(it['CLIENT_COUNTRY'] != clientCountry)
  jsonArray.add((new JSONObject()).put("CLIENT_COUNTRY","Multiple Client Countries Associated"));
}

I feel this code can be refactored/optimized to a better version in Groovy. Can someone please help me with it?

\$\endgroup\$
1
\$\begingroup\$

Putting the JSONArray aside (given I don't know the fully qualified name of the class), here's a Groovy-er version:

Working example

def invoiceList = [
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617151,SENDER_COUNTRY:'USA', CLIENT_COUNTRY:'USA'],
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617152,SENDER_COUNTRY:'CAD', CLIENT_COUNTRY:'MEX'],
    [INVOICE_DATE:20150617, INVOICE_NUMBER:617153,SENDER_COUNTRY:'CAD', CLIENT_COUNTRY:'MEX']
]

def senderCountry = invoiceList[0]['SENDER_COUNTRY']
def clientCountry  = invoiceList[0]['CLIENT_COUNTRY']

def result = invoiceList.inject([:]) { status, invoice ->
    if(invoice['SENDER_COUNTRY'] != senderCountry) status << ["SENDER_COUNTRY": "Multiple sender Countries Associated"]
    if(invoice['CLIENT_COUNTRY'] != clientCountry) status << ["CLIENT_COUNTRY":"Multiple Client Countries Associated"]

    status
}

if(result) {
    println "Not all invoices have the same sender and client countries."
} else {
    println "All good"
}

How it works

The inject() method iterates through the invoiceList and calls a closure with an object to aggregate with and the current item in the list. Iteration begins with an empty Map as the aggregated object, which remains empty unless the un-matching countries are found. When a mismatch occurs, it is recorded in the Map. The closure purposely returns the Map because the output of the closure is what's fed back in during the next iteration.

Finally, if the resulting Map is empty, then all of the countries are the same. Otherwise, the Map contains one or two keys indicating what the problem was.

If all you really need to know is whether all the countries matched or not, you can simply use every():

def result = invoiceList.every { invoice ->
    invoice['SENDER_COUNTRY'] == senderCountry && invoice['CLIENT_COUNTRY'] == clientCountry
}
| improve this answer | |
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.