patternjavaMinor
Groovy Map<String,List<Map<String,String>>> data manipulation method optimization
Viewed 0 times
mapmethodoptimizationmanipulationlistdatastringgroovy
Problem
Am trying to update the
Am trying to achieve below map
If the error message doesnt have a line number it need to be appended at the top level as
Otherwise errormessage should be appended to the matching INVOICE and linenumber as below
I wrote the below method to achieve the above
```
def regex = "^Line\\s(?:(\\d+)\\s)?\\s*:\\s+(\\d+)?.+";
for (e in invLineItems ){
def errors = lipErrors.findAll{it.invoiceNumber==e.key} // finding the error messages with the invoice number
errors.each{ // fetching th
Map>> invoices with the invoiceErrors as belowInvoiceError // is an entity with below attributes
{ String errorMessage,
String invoiceNumber
}
ErrorMessage invoiceNumber
------------- -------------------
File Error : The file is in an unsupported format INV-Error_Test1
Line : 1 Invoice does not foot Reported INV-Error_Test1
Line : 2 MATH ERROR INV-Error_Test1
Line : 3 MATH ERROR INV-Error_Test2
Line : 3 Invoice does not foot Reported INV-Error_Test2Am trying to achieve below map
If the error message doesnt have a line number it need to be appended at the top level as
invLineItems.put('error',['INV-Error_Test1' :File Error : The file is in an unsupported format])Otherwise errormessage should be appended to the matching INVOICE and linenumber as below
invLineItems = [INV-Error_Test1:[[LINE:1, INVOICE_DATE:20150301, INVOICE_NUMBER:INV-Error_Test1, INVOICE_TOTAL:22, error : `Line : 1 Invoice does not foot Reported`],
[LINE:2, INVOICE_DATE:20150301, INVOICE_NUMBER:INV-Error_Test1, INVOICE_TOTAL:24, error : `Line : 2 MATH ERROR`],
INV-Error_Test2:[[LINE:3, INVOICE_DATE:20150301, INVOICE_NUMBER:INV-Error_Test2, INVOICE_TOTAL:26, , error : `Line : 3 MATH ERROR | Line : 3 Invoice does not foot Reported`],
[LINE:4, INVOICE_DATE:20150301, INVOICE_NUMBER:INV-Error_Test2, INVOICE_TOTAL:28,]],
error : [[INV-Error_Test1:`File Error : The file is in an unsupported format`]]I wrote the below method to achieve the above
```
def regex = "^Line\\s(?:(\\d+)\\s)?\\s*:\\s+(\\d+)?.+";
for (e in invLineItems ){
def errors = lipErrors.findAll{it.invoiceNumber==e.key} // finding the error messages with the invoice number
errors.each{ // fetching th
Solution
You can use Groovy's regular expression operators to create Java Matchers.
In this example, I build the InvoiceError instances from a list that's transposed (btw, thank you for that trick). Each resulting map is coerced into an instance of InvoiceError.
I took a different approach by iterating through the errors and inserting them into the invoiceMap, rather than iterating through the invoiceMap and looking up the errors.
def invoices = [
'LEDES98BI V2',
'LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL',
'1|20150301|INV-Error_Test1|22',
'2|20150301|INV-Error_Test1|24',
'3|20150301|INV-Error_Test2|26',
'4|20150301|INV-Error_Test2|28,',
'5|20150301|INV WITH WHITESPACE|29,']
def lines = invoices
.findAll { it.contains('|') }
.collect { it.tokenize('|') }
def headers = lines.first()
def invoiceMap = lines.tail().collect{
[headers, it].transpose().collectEntries()
}.groupBy{ it.INVOICE_NUMBER }
class InvoiceError {
String errorMessage
String invoiceNumber
}
[
['INV-Error_Test1', 'File Error : The file is in an unsupported format'],
['INV-Error_Test1', 'Line : 1 Invoice does not foot Reported'],
['INV-Error_Test1', 'Line : 2 MATH ERROR'],
['INV-Error_Test2', 'Line : 3 MATH ERROR'],
['INV-Error_Test2', 'Line : 3 Invoice does not foot Reported']
].collect {
[['invoiceNumber', 'errorMessage'], it].transpose().collectEntries()
}.collect { it as InvoiceError }
.each {error ->
def matcher = error.errorMessage =~ /Line : (\d+) (.*)/
if(matcher) {
def lineNumber = matcher.group(1)
def errorDescription = matcher.group(2)
def line = invoiceMap[error.invoiceNumber]
.find() { it.LINE == lineNumber }
if(line.errors) {
line.errors = "$line.errors | $errorDescription"
} else {
line.errors = errorDescription
}
} else {
if(!invoiceMap.errors) invoiceMap.errors = []
invoiceMap.errors << [(error.invoiceNumber): error.errorMessage]
}
}
invoiceMapIn this example, I build the InvoiceError instances from a list that's transposed (btw, thank you for that trick). Each resulting map is coerced into an instance of InvoiceError.
I took a different approach by iterating through the errors and inserting them into the invoiceMap, rather than iterating through the invoiceMap and looking up the errors.
Code Snippets
def invoices = [
'LEDES98BI V2',
'LINE|INVOICE_DATE|INVOICE_NUMBER|INVOICE_TOTAL',
'1|20150301|INV-Error_Test1|22',
'2|20150301|INV-Error_Test1|24',
'3|20150301|INV-Error_Test2|26',
'4|20150301|INV-Error_Test2|28,',
'5|20150301|INV WITH WHITESPACE|29,']
def lines = invoices
.findAll { it.contains('|') }
.collect { it.tokenize('|') }
def headers = lines.first()
def invoiceMap = lines.tail().collect{
[headers, it].transpose().collectEntries()
}.groupBy{ it.INVOICE_NUMBER }
class InvoiceError {
String errorMessage
String invoiceNumber
}
[
['INV-Error_Test1', 'File Error : The file is in an unsupported format'],
['INV-Error_Test1', 'Line : 1 Invoice does not foot Reported'],
['INV-Error_Test1', 'Line : 2 MATH ERROR'],
['INV-Error_Test2', 'Line : 3 MATH ERROR'],
['INV-Error_Test2', 'Line : 3 Invoice does not foot Reported']
].collect {
[['invoiceNumber', 'errorMessage'], it].transpose().collectEntries()
}.collect { it as InvoiceError }
.each {error ->
def matcher = error.errorMessage =~ /Line : (\d+) (.*)/
if(matcher) {
def lineNumber = matcher.group(1)
def errorDescription = matcher.group(2)
def line = invoiceMap[error.invoiceNumber]
.find() { it.LINE == lineNumber }
if(line.errors) {
line.errors = "$line.errors | $errorDescription"
} else {
line.errors = errorDescription
}
} else {
if(!invoiceMap.errors) invoiceMap.errors = []
invoiceMap.errors << [(error.invoiceNumber): error.errorMessage]
}
}
invoiceMapContext
StackExchange Code Review Q#85679, answer score: 2
Revisions (0)
No revisions yet.