Power Query M 从多维列表递归创建 "Flat" 列表
Power Query M Recursively Creating a "Flat" List from a Multidimensional List
在 Power Query M 中,我正在尝试创建一个递归函数,将一团乱麻的多维列表和记录转换为一个平面记录列表,以便可以在 PowerBI 中轻松操作这些记录。
我用过其他语言的递归,但我对使用 M 还很陌生。
混乱的列表和记录在结构上与此类似:
- 事件
- 活动详情
- 付款
- 付款详情
存在一些细微差异,但应该无关紧要。
我希望输出与此类似:
{
[event1, eventDetail1, payment1, paymentDetails1],
[event1, eventDetail1, payment1, paymentDetails2],
[event1, eventDetail1, payment1, paymentDetails3],
[event1, eventDetail1, payment2, paymentDetails1],
}
针对每个项目继续。
这是我目前的递归函数:
recursiveCollapse = (uncleanedList as list, eventCounter as number, paymentCounter as number, finalList as list) =>
let
eventLength = List.Count(uncleanedList),
firstIf = if eventCounter < eventLength then
let
secondIf = if paymentCounter < List.Count(uncleanedList{eventCounter}[eventPayments]) then
finalList = @recursiveCollapse(uncleanedList, eventCounter, paymentCounter + 1, finalList & {
[
EventName = uncleanedList{eventCounter}[eventDetailName],
EventDescription = uncleanedList{eventCounter}[eventDetailDescription],
EventSaleStatus = uncleanedList{eventCounter}[eventDetailStatus],
EventFirstDate = uncleanedList{eventCounter}[eventDetailFirst],
EventLastDate = uncleanedList{eventCounter}[eventDetailLast],
PaymentID = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter}[id],
PaymentName = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter}[name],
PaymentCreated = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][created],
CustomerEmail = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][emailAddress],
CustomerFirstName = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][firstName],
CustomerLastName = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][lastName],
CustomerPhone = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][mobilePhone],
PaymentStatus = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][status],
PaymentTotal = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][totalPrice][value]
]
})
else
finalList = @recursiveCollapse(uncleanedList, eventCounter + 1, 0, finalList)
in
finalList
else
finalList
in
finalList,
dataTable = recursiveCollapse(allEventsLinks, 0, 0, {})
in
dataTable
在这个阶段 "dataTable" 只是 return 编辑为空 table。
我认为问题是由于 "finalList" 没有通过函数的递归调用正确地 returned。 M 没有 return 关键字,所以我不知道从这里该怎么做。
感谢任何帮助。
谢谢
我想通了。
对于任何需要帮助的人,这是我的解决方案:
recursiveCollapse = (uncleanedList as list, eventCounter as number, paymentCounter as
number, finalList as list) =>
let
returnList =
let
eventLength = List.Count(uncleanedList),
eventIf = if eventCounter < eventLength then
let
eventReturn = if paymentCounter + 1 < List.Count(uncleanedList{eventCounter}[eventPayments]) then
let
addRow =
finalList &
{
[
EventName = uncleanedList{eventCounter}[eventDetailName],
EventDescription = uncleanedList{eventCounter}[eventDetailDescription],
EventSaleStatus = uncleanedList{eventCounter}[eventDetailStatus],
EventFirstDate = uncleanedList{eventCounter}[eventDetailFirst],
EventLastDate = uncleanedList{eventCounter}[eventDetailLast],
PaymentID = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter + 1}[id],
PaymentName = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter + 1}[name],
PaymentCreated = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][created],
CustomerEmail = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][emailAddress],
CustomerFirstName = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][firstName],
CustomerLastName = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][lastName],
CustomerPhone = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][mobilePhone],
PaymentStatus = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][status],
PaymentTotal = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][totalPrice][value]
]
},
recursion = @recursiveCollapse(uncleanedList, eventCounter, paymentCounter + 1, addRow)
in
recursion
else
let
recursion = @recursiveCollapse(uncleanedList, eventCounter + 1, 0, finalList)
in
recursion
in
eventReturn
else
finalList
in
eventIf
in
returnList,
dataTable = Table.FromList(recursiveCollapse(allEventsLinks, 0, 0, {}), Record.FieldValues, {
"EventName",
"EventDescription",
"EventSaleStatus",
"EventFirstDate",
"EventLastDate",
"PaymentID",
"PaymentName",
"PaymentCreated",
"CustomerEmail",
"CustomerFirstName",
"CustomerLastName",
"CustomerPhone",
"PaymentStatus",
"PaymentTotal"
})
in
dataTable
在 Power Query M 中,我正在尝试创建一个递归函数,将一团乱麻的多维列表和记录转换为一个平面记录列表,以便可以在 PowerBI 中轻松操作这些记录。
我用过其他语言的递归,但我对使用 M 还很陌生。
混乱的列表和记录在结构上与此类似:
- 事件
- 活动详情
- 付款
- 付款详情
- 付款
- 活动详情
存在一些细微差异,但应该无关紧要。
我希望输出与此类似:
{
[event1, eventDetail1, payment1, paymentDetails1],
[event1, eventDetail1, payment1, paymentDetails2],
[event1, eventDetail1, payment1, paymentDetails3],
[event1, eventDetail1, payment2, paymentDetails1],
}
针对每个项目继续。
这是我目前的递归函数:
recursiveCollapse = (uncleanedList as list, eventCounter as number, paymentCounter as number, finalList as list) =>
let
eventLength = List.Count(uncleanedList),
firstIf = if eventCounter < eventLength then
let
secondIf = if paymentCounter < List.Count(uncleanedList{eventCounter}[eventPayments]) then
finalList = @recursiveCollapse(uncleanedList, eventCounter, paymentCounter + 1, finalList & {
[
EventName = uncleanedList{eventCounter}[eventDetailName],
EventDescription = uncleanedList{eventCounter}[eventDetailDescription],
EventSaleStatus = uncleanedList{eventCounter}[eventDetailStatus],
EventFirstDate = uncleanedList{eventCounter}[eventDetailFirst],
EventLastDate = uncleanedList{eventCounter}[eventDetailLast],
PaymentID = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter}[id],
PaymentName = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter}[name],
PaymentCreated = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][created],
CustomerEmail = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][emailAddress],
CustomerFirstName = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][firstName],
CustomerLastName = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][lastName],
CustomerPhone = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][customer][mobilePhone],
PaymentStatus = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][status],
PaymentTotal = uncleanedList{eventCounter}[eventPayments]{paymentCounter}[paymentDetail][totalPrice][value]
]
})
else
finalList = @recursiveCollapse(uncleanedList, eventCounter + 1, 0, finalList)
in
finalList
else
finalList
in
finalList,
dataTable = recursiveCollapse(allEventsLinks, 0, 0, {})
in
dataTable
在这个阶段 "dataTable" 只是 return 编辑为空 table。
我认为问题是由于 "finalList" 没有通过函数的递归调用正确地 returned。 M 没有 return 关键字,所以我不知道从这里该怎么做。
感谢任何帮助。
谢谢
我想通了。
对于任何需要帮助的人,这是我的解决方案:
recursiveCollapse = (uncleanedList as list, eventCounter as number, paymentCounter as
number, finalList as list) =>
let
returnList =
let
eventLength = List.Count(uncleanedList),
eventIf = if eventCounter < eventLength then
let
eventReturn = if paymentCounter + 1 < List.Count(uncleanedList{eventCounter}[eventPayments]) then
let
addRow =
finalList &
{
[
EventName = uncleanedList{eventCounter}[eventDetailName],
EventDescription = uncleanedList{eventCounter}[eventDetailDescription],
EventSaleStatus = uncleanedList{eventCounter}[eventDetailStatus],
EventFirstDate = uncleanedList{eventCounter}[eventDetailFirst],
EventLastDate = uncleanedList{eventCounter}[eventDetailLast],
PaymentID = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter + 1}[id],
PaymentName = uncleanedList{eventCounter}[eventPaymentDetails][refs]{paymentCounter + 1}[name],
PaymentCreated = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][created],
CustomerEmail = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][emailAddress],
CustomerFirstName = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][firstName],
CustomerLastName = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][lastName],
CustomerPhone = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][customer][mobilePhone],
PaymentStatus = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][status],
PaymentTotal = uncleanedList{eventCounter}[eventPayments]{paymentCounter + 1}[paymentDetail][totalPrice][value]
]
},
recursion = @recursiveCollapse(uncleanedList, eventCounter, paymentCounter + 1, addRow)
in
recursion
else
let
recursion = @recursiveCollapse(uncleanedList, eventCounter + 1, 0, finalList)
in
recursion
in
eventReturn
else
finalList
in
eventIf
in
returnList,
dataTable = Table.FromList(recursiveCollapse(allEventsLinks, 0, 0, {}), Record.FieldValues, {
"EventName",
"EventDescription",
"EventSaleStatus",
"EventFirstDate",
"EventLastDate",
"PaymentID",
"PaymentName",
"PaymentCreated",
"CustomerEmail",
"CustomerFirstName",
"CustomerLastName",
"CustomerPhone",
"PaymentStatus",
"PaymentTotal"
})
in
dataTable