java - Groovy method to build <String, List<List>> tokens from String array -


i have string array:

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,] 

i tried convert hasmap<string, list<list>> key invoice numbers(inv-error_test1, inv-error_test2) , values each invoice line:

[ inv-error_test2:[[3,20150301, inv-error_test2,26], [4,20150301, inv-error_test2,28]],  inv-error_test1:[[1,20150301, inv-error_test1,22], [2,20150301, inv-error_test1,24]] ] 

and method converts string array <string, list<list>> tokens:

def extractinvoicelineitems(def invoices) {     map invlineitems = new hashmap<string, arraylist<arraylist>>();     def lineitems = []     for(int = 2; i<invoices.length; i++){        def tokens =  invoices[i].split('\\|') list        if(tokens.size != 1) {         lineitems.add(tokens)                  }     }      (int i=0; i< lineitems.size; i++) {         invnumber = lineitems.get(i).get(1)          if(invlineitems.keyset().find{it == invnumber}) {             templineitem = invlineitems.get(invnumber)             templineitem.add(lineitems.get(i))             invlineitems.put(invnumber,templineitem)                }         else {             def list = []             list.add(lineitems.get(i))             invlineitems.put(invnumber,list)         }           } invlineitems } 

i using lots of traditional loops , wondering whether can simplified further (using closures or other way).

update1: trying print invoice details per invoice_number below

def lines = invoices*.split('\\|').findall{ it.size()>1 } def heads = lines.first() def invlineitems = lines.tail().collect{ [heads, it].transpose().collectentries() }.groupby{ it.invoice_number } // => [inv-error_test1:[[line:1, invoice_date:20150301, invoice_number:inv-error_test1, invoice_total:22], [line:2, invoice_date:20150301, invoice_number:inv-error_test1, invoice_total:24]], inv-error_test2:[[line:3, invoice_date:20150301, invoice_number:inv-error_test2, invoice_total:26], [line:4, invoice_date:20150301, invoice_number:inv-error_test2, invoice_total:28,]]]  println " inv-error_test2 details " invlineitems.get('inv-error_test2').each{      it.each{k,v -> print "line = "+ it['line'] print " "+" invoice_date = "+it['invoice_date'] print " "+" invoice_total  = "+it['invoice_total']     }  } 

but seeing map values when trying print specific value. can me out?

update2: trying update map<string,list<map<string,string>>> invoices invoiceerrors below

invoiceerror // entity below attributes { string errormessage,   string invoicenumber     } errormessage                                          invoicenumber    -------------                                       -------------------      file error : file in unsupported format   inv-error_test1 line : 1 invoice not foot reported             inv-error_test1 line : 2 math error                                 inv-error_test1 line : 3 math error                                 inv-error_test2 line : 3 invoice not foot reported             inv-error_test2 

am trying achieve below map if error message doesnt have line number need appended @ top level invlineitems.put('error',['inv-error_test1' :file error : file in unsupported format]) otherwise errormessage should appended matching invoice , linenumber below

invlineitems = [inv-error_test1:[[line:1, invoice_date:20150301, invoice_number:inv-error_test1, invoice_total:22, error : `line : 1 invoice 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 not foot reported`],                                  [line:4, invoice_date:20150301, invoice_number:inv-error_test2, invoice_total:28,]],                 error : [[inv-error_test1:`file error : file in unsupported format`]] 

i wrote below method achieve above

def regex = "^line\\s(?:(\\d+)\\s)?\\s*:\\s+(\\d+)?.+"; (e in invlineitems ){   def errors =  liperrors.findall{it.invoicenumber==e.key} // finding error messages invoice number   errors.each{  // fetching line numbre error message , finding matching record invoice number , line number in invlineitems       int linenumber      if (it.errormessage.matches(regex)) {             pattern p = pattern.compile("\\d+");             matcher m = p.matcher(it.errormessage);             if (m.find()) {                  linenumber = integer.parseint(m.group());             }           println "linenumber = "+linenumber         }      if(e.value['line_item_number'].find{it==linenumber.tostring()}) {       def data = liperrors.findall{it.invoicenumber==e.key && it.errormessage.matches("^line\\s+"+linenumber+"?\\:\\s+"+linenumber+"?.+")}       e.getvalue().each{it.put("error", data.errormessage.join("|"))}       }       } }    

the code doesnt groovy , using traditional java code mostly, wondering whether code can simplified groovy approach

what after groupby

this should do:

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,']  // "valid" lines def lines = invoices*.split('\\|').findall{ it.size()>1 } // remember keys (headline) later (optional) def heads = lines.first()  // map of maps println lines.tail().collect{ [heads, it].transpose().collectentries() }.groupby{ it.invoice_number } // => [inv-error_test1:[[line:1, invoice_date:20150301, invoice_number:inv-error_test1, invoice_total:22], [line:2, invoice_date:20150301, invoice_number:inv-error_test1, invoice_total:24]], inv-error_test2:[[line:3, invoice_date:20150301, invoice_number:inv-error_test2, invoice_total:26], [line:4, invoice_date:20150301, invoice_number:inv-error_test2, invoice_total:28,]]]  // or had (map of string list) println lines.tail().groupby{ it[2] } // => [inv-error_test1:[[1, 20150301, inv-error_test1, 22], [2, 20150301, inv-error_test1, 24]], inv-error_test2:[[3, 20150301, inv-error_test2, 26], [4, 20150301, inv-error_test2, 28,]]] 

edit

version prints lines invoice number:

def invlineitems = lines.tail().collect{ [heads, it].transpose().collectentries() }.groupby{ it.invoice_number } 

this a map<string,list<map<string,string>>>. getting 1 element gives list. each iterates list , it there map:

invlineitems.get('inv-error_test2').each{          print "line = "+ it['line']         print " "+" invoice_date = "+it['invoice_date']         print " "+" invoice_total  = "+it['invoice_total']         println "" } 

or quick dirty:

print invlineitems.get('inv-error_test2')*.collect{ k, v -> [k,"=",v].join(" ") }*.join(", ").join("\n") 

Comments

Popular posts from this blog

How to run C# code using mono without Xamarin in Android? -

c# - SharpSsh Command Execution -

python - Specify path of savefig with pylab or matplotlib -