如何在 Mule Dataweave 中作为一个循环和组合
How to loop and combine as one in Mule Dataweave
我有 json 的请求和如下所述的预期响应。它需要 groupBy clientItemCode
并且我在某个地方卡住了一半以相同的方式循环。同时使用 MapObject
和 reduce
组合函数。任何帮助将不胜感激。
[
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "CLOSED"
},
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "OPEN"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "CHECKOUT"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "TEST"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "OPEN"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "CLOSED"
}
]
预期响应:
<Results>
<Result>
<ClientItemCode>123<ClientItemCode>
<ResultLines>
<ResultLine>
<ClientCode>1</ClientCode>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLine>
<ResultLine>
<ClientCode>2</ClientCode>
<From>
<LocationId>CHECKOUT</LocationId>
</From>
<To>
<LocationId>TEST</LocationId>
</To>
</ResultLine>
</ResultLines>
</Result>
<Result>
<CientItemCode>245<ClientItemCode>
<ResultLines>
<ResultLine>
<ClientCode>1</ClientCode>
<From>
<LocationId>CLOSED</LocationId>
</From>
<To>
<LocationId>OPEN</LocationId>
</To>
</ResultLine>
</ResultLines>
</Result>
</Results>
假设 OPEN and/or CLOSED 可能丢失:
%dw 2.0
output application/xml
---
Results: payload groupBy $.ClientItemCode
mapObject ((value, key, index) -> result: {
ClientItemCode: key,
ResultLines: {
From: if (value.LocationId contains "OPEN") LocationId: "OPEN" else null,
To: if (value.LocationId contains "CLOSED") LocationId: "CLOSED" else null
}
}
)
输出:
<?xml version='1.0' encoding='UTF-8'?>
<Results>
<result>
<ClientItemCode>245</ClientItemCode>
<ResultLines>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLines>
</result>
<result>
<ClientItemCode>123</ClientItemCode>
<ResultLines>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLines>
</result>
</Results>
这是我想出来的,如果我有更多时间投入,可能会稍微简化一下。试一试:
%dw 2.0
output application/xml
var data = [
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "CLOSED"
},
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "OPEN"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "CHECKOUT"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "TEST"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "OPEN"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "CLOSED"
}
]
---
// I assume that your data are ordered and all the records that will be From and To
// are paired with one another. It is doable without making such assumption but the
// algorithm will get complex.
results: do {
// Group by the data
var groupedData = data map {($),(From: true) if (isEven($$))} groupBy $.ClientItemCode
// Order the client Ids
var orderedClientIds = groupedData pluck $$ orderBy $ as Number
---
orderedClientIds reduce (cId, results={}) -> do {
var clientItemCode = cId
var groupedByClientICode = groupedData[cId] groupBy $.ClientCode pluck $
---
results ++ {result: {
ClientItemCode: clientItemCode,
ResultLines: groupedByClientICode reduce (cliCode, lines={}) -> do {
var clientCode = cliCode[0].ClientCode
---
lines ++ {
ClientCode: clientCode,
ResultLine: cliCode reduce (e, acc={}) -> do {
var locRec = {LocationId: e.LocationId}
---
acc ++ (if (e.From?) {From: locRec } else {To: locRec})
}
}
}
}}
}
}
我在评论中复制时也做了一个假设:我假设你的数据是有序的,所有 From
和 To
的记录都相互配对。
编辑:再次编辑代码以强制对 ClientItemCode
进行排序,然后在创建 result
标签的所有转换之前按顺序访问每个值。其余代码与之前几乎相同。不确定为什么一个简单的 orderBy
对你不起作用,但它对我有用。
我有 json 的请求和如下所述的预期响应。它需要 groupBy clientItemCode
并且我在某个地方卡住了一半以相同的方式循环。同时使用 MapObject
和 reduce
组合函数。任何帮助将不胜感激。
[
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "CLOSED"
},
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "OPEN"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "CHECKOUT"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "TEST"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "OPEN"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "CLOSED"
}
]
预期响应:
<Results>
<Result>
<ClientItemCode>123<ClientItemCode>
<ResultLines>
<ResultLine>
<ClientCode>1</ClientCode>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLine>
<ResultLine>
<ClientCode>2</ClientCode>
<From>
<LocationId>CHECKOUT</LocationId>
</From>
<To>
<LocationId>TEST</LocationId>
</To>
</ResultLine>
</ResultLines>
</Result>
<Result>
<CientItemCode>245<ClientItemCode>
<ResultLines>
<ResultLine>
<ClientCode>1</ClientCode>
<From>
<LocationId>CLOSED</LocationId>
</From>
<To>
<LocationId>OPEN</LocationId>
</To>
</ResultLine>
</ResultLines>
</Result>
</Results>
假设 OPEN and/or CLOSED 可能丢失:
%dw 2.0
output application/xml
---
Results: payload groupBy $.ClientItemCode
mapObject ((value, key, index) -> result: {
ClientItemCode: key,
ResultLines: {
From: if (value.LocationId contains "OPEN") LocationId: "OPEN" else null,
To: if (value.LocationId contains "CLOSED") LocationId: "CLOSED" else null
}
}
)
输出:
<?xml version='1.0' encoding='UTF-8'?>
<Results>
<result>
<ClientItemCode>245</ClientItemCode>
<ResultLines>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLines>
</result>
<result>
<ClientItemCode>123</ClientItemCode>
<ResultLines>
<From>
<LocationId>OPEN</LocationId>
</From>
<To>
<LocationId>CLOSED</LocationId>
</To>
</ResultLines>
</result>
</Results>
这是我想出来的,如果我有更多时间投入,可能会稍微简化一下。试一试:
%dw 2.0
output application/xml
var data = [
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "CLOSED"
},
{
"ClientCode": "1",
"ClientItemCode": "245",
"LocationId": "OPEN"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "CHECKOUT"
},
{
"ClientCode": "2",
"ClientItemCode": "245",
"LocationId": "TEST"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "OPEN"
},
{
"ClientCode": "1",
"ClientItemCode": "123",
"LocationId": "CLOSED"
}
]
---
// I assume that your data are ordered and all the records that will be From and To
// are paired with one another. It is doable without making such assumption but the
// algorithm will get complex.
results: do {
// Group by the data
var groupedData = data map {($),(From: true) if (isEven($$))} groupBy $.ClientItemCode
// Order the client Ids
var orderedClientIds = groupedData pluck $$ orderBy $ as Number
---
orderedClientIds reduce (cId, results={}) -> do {
var clientItemCode = cId
var groupedByClientICode = groupedData[cId] groupBy $.ClientCode pluck $
---
results ++ {result: {
ClientItemCode: clientItemCode,
ResultLines: groupedByClientICode reduce (cliCode, lines={}) -> do {
var clientCode = cliCode[0].ClientCode
---
lines ++ {
ClientCode: clientCode,
ResultLine: cliCode reduce (e, acc={}) -> do {
var locRec = {LocationId: e.LocationId}
---
acc ++ (if (e.From?) {From: locRec } else {To: locRec})
}
}
}
}}
}
}
我在评论中复制时也做了一个假设:我假设你的数据是有序的,所有 From
和 To
的记录都相互配对。
编辑:再次编辑代码以强制对 ClientItemCode
进行排序,然后在创建 result
标签的所有转换之前按顺序访问每个值。其余代码与之前几乎相同。不确定为什么一个简单的 orderBy
对你不起作用,但它对我有用。