【发布时间】:2015-06-06 12:54:03
【问题描述】:
我有一个字符串数组:
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,]
我尝试将其转换为 HasMap<String, List<List>>,并将键作为发票编号(INV-Error_Test1,INV-Error_Test2),值是每个发票行:
[
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]]
]
这是将字符串数组转换为<String, List<List>>标记的方法:
def extractInvoiceLineItems(def invoices) {
Map invLineItems = new HashMap<String, ArrayList<ArrayList>>();
def lineItems = []
for(int i = 2; i<invoices.length; i++){
def tokens = invoices[i].split('\\|') as List
if(tokens.size != 1) {
lineItems.add(tokens)
}
}
for (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
}
我使用了很多传统的 for 循环,想知道是否可以进一步简化(使用闭包或任何其他方式)。
更新1:
我正在尝试按INVOICE_NUMBER 打印发票详细信息,如下所示
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']
}
}
但在尝试打印特定值时会看到所有地图值。有人可以帮帮我吗?
UPDATE2:我正在尝试使用下面的 invoiceErrors 更新 Map<String,List<Map<String,String>>> invoices
InvoiceError // 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_Test2
我正在尝试实现以下地图
如果错误消息没有行号,则需要在顶层附加为invLineItems.put('error',['INV-Error_Test1' :File Error : The file is in an unsupported format])
否则错误消息应附加到匹配的 INVOICE 和 linenumber 如下
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`]]
我写了下面的方法来实现上面的
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 the line numbre from error message and finding the matching record the invoice number and 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("|"))}
}
}
}
代码看起来不像Groovy,主要是使用传统的java代码,想知道代码是否可以用Groovy的方法来简化
【问题讨论】:
-
能否请您提供带有
.inspect()输出的数据 - 这个无效的“字符串”实际上无法编写一些代码来测试它。 -
查看更新后问题答案的评论
-
我删除了 `k,v` 并尝试了
it['LINE'],但遇到错误 groovy.lang.MissingPropertyException: No such property: get for class: java.util.LinkedHashMap$Entry 可能的解决方案:key
标签: java optimization groovy