2017-05-10 56 views
2

invoiceList如下這是一個List<Map<String:String>>,我試圖findout如果所有的發票都相同SENDER_COUNTRYCLIENT_COUNTRY與否,如果沒有這將增加消息JSON陣列Groovy:在優化代碼,以查找重複元素

[ 
    [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")); 
} 

我覺得這個代碼可以在Groovy中重構/優化到更好的版本,有人可以幫我一下嗎?

+0

RanPaul,看看提供的解決方案是否更好? – Rao

回答

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))​ 
+0

它不工作,如果所有'SENDER_COUNTRY'值是相同的和所有'CLIENT_COUNTRY'值是相同的 – RanPaul

+0

@RanPaul,我沒有看到這樣的行爲。它確實按照要求工作,再次檢查它。請參閱[demo](http://groovyconsole.appspot.com/script/5191556013228032)。或者你顯示數據/結果(如果可能,添加屏幕截圖) – Rao

+0

@RanPaul,你重新檢查過它嗎?這是你想要優化還是尋找更多東西?如果解決方案,請確認它是否被接受爲答案。 – Rao

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"}] 
+0

這樣做相當於循環整個數組以映射到 - > CLIENT_COUNTRY,然後唯一循環再次找到重複項。這比原來的要糟糕得多。 – Raphael

+1

@Raphael我同意你的評論,但我覺得這個問題是關於風格的「更好的Groovy版本」,而不是性能。 – sebnukem

+0

理想,它可能 – Raphael

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。