Q:如何动态扩展记录

问题描述 投票:0回答:1

我有一个用例,其中有多个列包含要动态扩展的记录。意味着要扩展的列的名称不是硬编码的。

Expanded = Table.ExpandRecordColumn(Source, "HardcodedColumnName", {"fieldname"}, {"fieldname"}),

下面的我的M代码可以基于转换表动态扩展记录。但是我也无法理解如何动态扩展列名。对于上下文,我的实际数据集有很多列需​​要扩展,并且列的数量会随时间而变化。我正在寻找扩展所有这些列的可扩展方法。

let
   //Use-case: dynamically expand 'name for 'user' and 'timezone' for 'city',
   //          i e expand records w/o hardcoded column- or field names

   Source = Table.FromRecords(
            {
               [key = 1, user = [id = 10, name = "Wayne Carter"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]],
               [key = 2, user = [id = 20, name = "Hugh Jass"], city = [id = 1, name = "Milan", timezone = "Central European Time"]],
               [key = 3, user = [id = 30, name = "Ben Dover"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]]
            }),

   //Table controls which attribute to expand
   TransformationTable = Table.FromRecords(
            {
               [field = "user", attribute = "name"],
               [field = "city", attribute = "timezone"]
            }),

   //Transformation table lookup
   AttributeLookup = (parameter as text) =>
   let 
      value = Table.SelectRows(TransformationTable, each ([field] = parameter))[attribute]{0}
   in
      value,

   //These rows are hardcoded for columns 'user' and 'city' - how to make this dynamic?
   ExpandedTable1 = Table.ExpandRecordColumn(Source, "user", {AttributeLookup("user")}, {AttributeLookup("user")}),
   ExpandedTable2 = Table.ExpandRecordColumn(ExpandedTable1, "city", {AttributeLookup("city")}, {AttributeLookup("city")}),

in
   ExpandedTable2

excel transformation powerquery
1个回答
0
投票

我认为您可以使用下面的代码来实现这一目标:

let
    someTable = Table.FromRecords({
        [key = 1, user = [id = 10, name = "Wayne Carter"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]],
        [key = 2, user = [id = 20, name = "Hugh Jass"], city = [id = 1, name = "Milan", timezone = "Central European Time"]],
        [key = 3, user = [id = 30, name = "Ben Dover"], city = [id = 2, name = "Wuhan", timezone = "China Standard Time"]]
    }),
    expansionMap = [
        user = {"name"},
        city = {"timezone"}
    ],
    dynamicallyExpanded = List.Accumulate(Record.FieldNames(expansionMap), someTable, (tableState as table, recordColumnName as text) as table =>
        let
            fieldNamesToExpand = Record.Field(expansionMap, recordColumnName),
            fieldNamesAfterExpansion = fieldNamesToExpand,
            expanded = Table.ExpandRecordColumn(tableState, recordColumnName, fieldNamesToExpand, fieldNamesAfterExpansion)
        in expanded
    )
in
    dynamicallyExpanded
  • expansionMaprecord,其中:
    • 字段名称(即usercity)映射到包含记录的列的名称(需要扩展)
    • 字段值(即{"name"}{"timezone"})映射到嵌套字段(最终将成为扩展表中的列)。
  • 上面的所有代码所做的是遍历expansionMap中的字段名称,同时迭代扩展每个指定的记录列。
  • 表中的列名必须是唯一的,因此,例如,如果您指定要在id记录列中扩展user,并在id记录列中扩展city,我想您应该最终得到一个错误(假设已经有一个名为id的列)。为了避免这种情况,您可以实施一些逻辑来重命名扩展的列,使它们不匹配任何现有的列名。例如,您可以将代码中的相关行更改为:fieldNamesAfterExpansion = List.Transform(fieldNamesToExpand, each Text.Combine({recordColumnName, _}, ".")),

这不是真正的动态。也就是说,您在编写代码时就已经知道记录列的名称(要扩展)。但是,如果我正确理解了您的问题,那么您只想通过某种抽象结构来表示您的记录列,并编写一些可以使用/处理该结构的代码。

© www.soinside.com 2019 - 2024. All rights reserved.