从每个访问以前返回的值?

时间:2019-05-23 20:23:33

标签: c# excel lambda powerquery m

在C#中,我可以这样写:

int? valueForNewColumeInPreviousRecord = null;

myTable.AddColumn("New Column Name", (record) => {
                                        int newColumeValue;
                                        newColumeValue = valueForNewColumeInPreviousRecord.HasValue ?
                                                            valueForNewColumeInPreviousRecord.Value + record.SomeOtherValue : 
                                                            record.SomeOtherValue;

                                        valueForNewColumeInPreviousRecord = newColumeValue;

                                        return newColumeValue;
                                    } + 42);

注意:+ 42部分,使得无法从表中的任何记录读取/获取/访问最后返回的值。

我将如何在Power Query中执行此操作? 还是在那里有完全不同的方法来做这种事情?

我对在表中实际添加新列不感兴趣,但是对从lambda /每个访问先前返回的/计算的数据,以及在可能的情况下如何将数据存储在变量中的实际概念不感兴趣。

桌子上的东西只是一个很好的具体例子,您可能想做类似的事情。

2 个答案:

答案 0 :(得分:0)

我不是很肯定,但这与List.AccumulateList.Generate之类的功能允许您执行的操作非常相似。

这些与循环类似,在循环访问列表时初始化和更新值。

答案 1 :(得分:0)

您可以执行此操作,但是使用大表的速度非常慢。让我们来看一个运行示例。

使用名为“ Source”的表,该表的“ Values”列中包含要累加的数字。

要做的第一件事是添加索引列。

Indexed = Table.AddIndexColumn(Source, "Index"),

然后,按照您的问题,添加一个名为“ RunTot”的新列。该新列的每个值都是该行“值”中的数字加上之前的运行总计(“ RunTot”)。技巧是在“ @Output [RunTot] {[Index] -1}”这一部分之前的“ @”符号,以此方式调用正在构造的列的上一个元素。

“尝试...否则”只是一种避免将负索引传递给列表时出错的方法。

最后,“ Table.Buffer”是一种加快思考速度的方法。

Output = Table.Buffer(Table.AddColumn(Indexed, "RunTot", each [Values] + (try @Output[RunTot]{[Index]-1} otherwise 0)))

但是正如Alexis所建议的,“ List.Generat”方法要好得多。这是使用List.Generate运行的合计函数:

fnListGenerateRunningTotal = (Input as list) as list => 
List.Generate( 
        ()=> [Total = Input{0}, Counter = 0],
        each [Counter] < List.Count(Input),
        each [Total = Input{Counter} + [Total], Counter = [Counter] + 1],
        each [Total]
    )