Groovy程式碼優化-遞迴格式化引數
阿新 • • 發佈:2018-12-04
根據現在的分享活動返回的報文中帶有amount以及time的資料,老大希望能將他們格式化成希望的格式,並且希望能寫一個通用的服務來調取這樣的功能。。。
由於報文的格式各種各樣。。。such as …
def c = [
hhh : 123123,
amount: 90
]
def b = [
name : 'cqc',
amount: 123213,
]
Map a = [
id : 1,
amount: 234,
desc : 'asdasd',
user : [b, c]
]
Map d = [
rewardDays: 72,
cashedAmount: 170.00,
rewardAmounts: 200.00,
billCount: null,
detail: [
[
rewardDays: 2,
status: 1,
amount: null,
time: 'FriMar0310: 23 : 57CST2017',
licensePlateNo: null
],
[
rewardDays: null,
status: 1,
amount: 120.0,
time: 'FriMar0310: 23: 57CST2017',
licensePlateNo: null
],
[
rewardDays: 30,
status: 1,
amount: 50.0,
time: 'FriMar0310: 23: 57CST2017',
]
]
]
以上都是比較普遍的,還有個別比較特殊的資料格式還沒考慮進來。。。
該資料格式比較適用於多叉樹查詢。。。遞迴呼叫。。。我用的方法比較暴力,找到這個樹的根然後遞迴呼叫這個節點,當遍歷葉子的時候找到包含amount或者time的葉子就將其格式化,並將其格式化後的資料新增到原來的節點裡,由於該資料結構為map形式,所以將會替代原來的value值,趕腳很浪費空間。。。
def displayDetail(User user) {
List<Map> offerDetails = this.offerDetails(user)
Map responseMap = this.offerGeneral(user)
responseMap.put('detail', offerDetails);
this.amountFormat(responseMap)
}
def amountFormat(resultMap) {
if (!resultMap) {
return
}
resultMap.collectEntries {
if (it.key.toLowerCase().contains('amount')) {
[it.key, it.value ? DoubleUtils.displayStringWithDecimal(it.value, 2) : 0.00]
} else if (it.key.toLowerCase().contains('time')) {
[it.key, DateUtils.getDateString(it.value, DateUtils.DATE_LONGTIME24_PATTERN2)]
} else if (it.value instanceof Map) {
[it.key, amountFormat(it.value)]
} else if (it.value instanceof List) {
[it.key, it.value.collect { ti ->
[amountFormat(ti)]
}.flatten()]
} else {
it
}
}
}
老大提供一個思路。。。先找葉子更改其value值,雖然剛開始我也是用這個思路,但是遍歷更改value值得過程中,map會產生新的地址存放這個值,所以一時半會也不知道怎麼解決這個問題,所以才換了一個思路。。。但是老大還是找到了問題的關鍵。。。使程式碼的重用度更高。。。
def displayDetail(User user) {
List<Map> offerDetails = this.offerDetails(user)
Map responseMap = this.offerGeneral(user)
responseMap.put('detail', offerDetails);
// this.amountFormat(responseMap)
eachLeaf responseMap, { entry ->
if(entry.key.toLowerCase().contains('amount')) {
entry.value = entry.value ? DoubleUtils.displayStringWithDecimal(entry.value, 2) : 0.00
} else if(entry.key.toLowerCase().contains('time')){
entry.value = DateUtils.getDateString(entry.value, DateUtils.DATE_SHORTDATE2_PATTERN)
}
}
}
def eachLeaf(value, entry=null, Closure runOnLeaf){
if(value instanceof Map){
value.each{
eachLeaf(it.value, it, runOnLeaf)
}
} else if(value instanceof List){
value.each{
eachLeaf(it, runOnLeaf)
}
} else {
if(entry){
runOnLeaf(entry)
}
}
}
老大使用了閉包使整個遞迴的呼叫更加靈活!!!
現在還有一個新的需求就是當資料結構中包含list的基礎資料型別,無法處理。。。
def a = [
amount: [1,2,3,4]
...
]
如果有比較好的方法或者思路歡迎提供!!!