首页 > 解决方案 > 如何在Dataweave中将按小时分隔的连续日期组合在一起?

问题描述

我有以下输入数据,我试图将连续的 DateTime 组合在一起,以 hr 递增。使用的版本:Dataweave 2.3、Mule 4.3

Input data.
["2020-03-03T06:00:00", "2020-03-03T07:00:00", "2020-03-03T08:00:00", 
"2020-03-03T09:00:00", "2020-03-03T13:00:00", "2020-03-03T14:00:00", 
"2020-03-03T15:00:00", "2020-03-04T06:00:00", "2020-03-04T07:00:00", 
"2020-03-04T08:00:00", "2020-03-04T09:00:00"]

业务逻辑:从上面的输入中,一些数据是按小时连续的。索引 (0,1,2,3) 和 (4,5,6) 和 (7,8,9,10) 按小时分组。目的是将这些连续的日期合并在一起,并创建如下的对象集,其中 fromDate 是该组的最低日期,toDate 是该组的最高日期。希望我清楚要求。

Expected Output.
[{"fromDate" : "2020-03-03T06:00:00", "toDate" : "2020-03-03T09:00:00" },
 {"fromDate" : "2020-03-03T13:00:00", "toDate" : "2020-03-03T15:00:00" },
 {"fromDate" : "2020-03-04T06:00:00", "toDate" : "2020-03-04T09:00:00" }]

我已经尝试过 map、groupby、reduce 但无法解决这个问题。请帮忙。

标签: muledataweavemulesoft

解决方案


非常有趣的挑战。为了做到这一点,我实现了一个名为 clusterBy 的函数,它将匹配给定条件的连续元素分组。一旦我有了,我只需要将每个集群的第一个和最后一个映射到对象中。请参阅下面的代码

%dw 2.0 
fun clusterWhile<T>(elements: Array<T>,  criteria: (source:T, target:T) -> Boolean) = do {
    fun clusterLoop(elements, value, carrier, criteria) = 
        elements  match {
            case [] ->  carrier
            case [x ~ xs] ->  
                if(criteria(value, x)) do {
                    var updatedCarrier = carrier update {
                        case [-1] -> $ << x    
                    }
                    ---
                    clusterLoop(xs, x, updatedCarrier, criteria)
                }
            else 
                clusterLoop(xs, x, carrier << [x], criteria)
    }

    ---
    elements match {
        case [] -> []
        case [x ~ xs] -> clusterLoop(xs, x, [[x]], criteria)
    }
}    


---
payload 
    clusterWhile ((source, target) -> target as DateTime - source as DateTime == |PT1H|)
    map ((item, index) -> {
        fromDate: item[0],
        toDate: item[-1]
})

推荐阅读