Groovy:优化代码以查找重复元素

时间:2017-05-10 00:13:09

标签: performance optimization groovy

我有invoiceList,如下List<Map<String:String>>,我正在尝试查看所有发票是否都有相同的SENDER_COUNTRYCLIENT_COUNTRY,否则会添加[ [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")); } 消息到JSON数组

Thread.sleep()

我觉得这个代码可以在Groovy中重构/优化为更好的版本,有人可以帮助我吗?

3 个答案:

答案 0 :(得分:2)

这个怎么样(注意我的答案没有改善表现):

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 jsonarray = []
if (invoiceList.countBy{ it.CLIENT_COUNTRY }.size > 1)
     jsonarray << [CLIENT_COUNTRY: "Multiple client countries associated"]
if (invoiceList.countBy{ it.SENDER_COUNTRY }.size > 1)
     jsonarray << [SENDER_COUNTRY: "Multiple sender countries associated"]

groovy.json.JsonOutput.toJson(jsonarray)
// Result: [{"CLIENT_COUNTRY":"Multiple client countries associated"},{"SENDER_COUNTRY":"Multiple sender countries associated"}] 

答案 1 :(得分:1)

如果您可以向项目添加新库,则可以使用GPars:

@Grab(group='org.codehaus.gpars', module='gpars', version='1.0.0') 
import static groovyx.gpars.GParsPool.withPool

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 jsonArray = []
def senderCountry = invoiceList[0]['SENDER_COUNTRY']
def clientCountry  = invoiceList[0]['CLIENT_COUNTRY']

withPool( 4 ) {             
    invoiceList.eachParallel{  
        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"))
    }         
}

​

这将创建一个包含4个工作线程的线程池,它们将并行扫描invoiceList。

答案 2 :(得分:1)

这是另一个实现相同目的的版本。

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 getFilteredList = { map ->
    map.collect{ k,v -> invoiceList.countBy{ it."$k" }.findAll{it.value > 1}.collectEntries{[it.key,v] } }
}

//You may change the description in the values of below map
def findEntries = [CLIENT_COUNTRY: 'Multiple Client Countries found', SENDER_COUNTRY: 'Multiple Sender Countries found']
println groovy.json.JsonOutput.toJson(getFilteredList(findEntries))

<强>输出:

[{"MEX":"Multiple Client Countries found"},{"CAD":"Multiple Sender Countries found"}]

您可以快速在线试用 Demo

编辑: OP要求提供其他信息,说明如果所有client countrysender country都相同,它也应该返回空。

使用以下脚本:

def invoiceList = [
  [INVOICE_DATE:20150617, INVOICE_NUMBER:617151,SENDER_COUNTRY:'CAD', 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 getFilteredList = { map->
    map.collect{ k,v -> invoiceList.countBy{ it."$k" }.findAll{it.value > 1  && (it.value != invoiceList.size())}.collectEntries{ [it.key,v] } }.findAll{it.size()>0}
}

//You may change the descript in the values of below map
def findEntries = [CLIENT_COUNTRY: 'Multiple Client Countried found', SENDER_COUNTRY: 'Multiple Sender Countries found']
println groovy.json.JsonOutput.toJson(getFilteredList(findEntries))​

快速在线试用 Demo

EDIT2: OP进一步请求修改以将输出更改为

[ {"message", "Multiple clients, Multiple sender"}]
def invoiceList = [
  [INVOICE_DATE:20150617, INVOICE_NUMBER:617151,SENDER_COUNTRY:'CAD1', 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 getFilteredList = { map->
    def result = map.collect{ k,v -> invoiceList.countBy{ it."$k" }.findAll{it.value > 1  && (it.value != invoiceList.size())}.collect{ v } }.findAll{it.size()>0}
    result ? [[message : result.flatten().join(',') ]] : []
}

//You may change the descript in the values of below map
def findEntries = [CLIENT_COUNTRY: 'Multiple Client Countried found', SENDER_COUNTRY: 'Multiple Sender Countries found']
println groovy.json.JsonOutput.toJson(getFilteredList(findEntries))​