1. 程式人生 > >Groovy程式碼優化-遞迴格式化引數

Groovy程式碼優化-遞迴格式化引數

根據現在的分享活動返回的報文中帶有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]
  ...
]

如果有比較好的方法或者思路歡迎提供!!!