power query Function.ScalarVector函数优化调用 M 函数

      今天学习一下在power query中使用Function.ScalarVector函数来优化我们调用的M函数公式。本例来自老外的博客文章:https://blog.crossjoin.co.uk/2018/11/16/function-scalarvector-optimise-power-query-m-functions/,我想试着按照原英文的步骤,来熟悉一下这个函数的使用。我们先看一下这个函数的基本解释:

这个函数能够使你将批量的函数请求和单行请求结合起来。下面我会跟着老外的例子来走一遍,熟悉理解下。下面是一个叫SingleValueUpper的函数,作用很简单,英文小写转大写:

(InputText as text) => Text.Upper(InputText)

现在创建一个名叫Product的表(table):

#table(
    type table [Fruit=text],
    {{"apples"},{"oranges"},{"pears"}}
    )

 平常一般做法就是Table.AddColumn(Product, "Fruit Upper", each SingleValueUpper([Fruit]))实现大小写转换。日常代码:

let
    SingleValueUpper=(InputText as text) =>Text.Upper(InputText),
    Product = #table(
    type table [Fruit=text],
    {{"apples"},{"oranges"},{"pears"}}
    ),
    res=Table.AddColumn(Product, "Fruit Upper", each SingleValueUpper([Fruit]))

in
    res

结果:

在上面的例子里,SingleValueUpper函数被调用了3次,每一行调用了一次。如果是这样调用网络服务的话,效率会非常的低。

现在来看看ListUpper函数:

(InputText as list) => 
    List.Transform(
        InputText, 
        each Text.Upper(_)
        )

这个函数接受一个文本列表,并把里面的每个值转化为大写并返回一个列表结果。上面的例子我们可以通过ListUpper(Product[Fruit])就获得了水果的列表并完成转换了。 如果你是这样调用网络服务,会更高效。

Function.ScalarVector可以像这样通过引发函数开关来调用函数。来看下自定义一个ScalarVectorUpper函数:

Function.ScalarVector(
    type function(Fruit as text) as text,
    (InputTable) =>
        let
            BufferTable = Table.Buffer(InputTable),
            InputList = BufferTable[Fruit],
            CallFunction = ListUpper(InputList)            
        in
            CallFunction
)

 我们这里可以看到Function.ScalarVector的两个参数了:

第一个参数,匹配我们在调用的表的列的函数类型。

第二个参数,传递一个和函数类型(第一参数)相同列的表。文档里面说这个函数不能对表枚举超过一次。所以需要使用 Table.Buffer() 函数将表缓冲到内存里面,隔壁外部环境。

查询的代码如下;

let 
    ListUpper=(InputText as list) => 
    List.Transform(
        InputText, 
        each Text.Upper(_)
        ),

    ScalarVectorUpper=Function.ScalarVector(
    type function(Fruit as text) as text,
    (InputTable) =>
        let
            BufferTable = Table.Buffer(InputTable),
            InputList = BufferTable[Fruit],
            CallFunction = ListUpper(InputList)            
        in
            CallFunction
    ),

    Product = #table(
    type table [Fruit=text],
    {{"apples"},{"oranges"},{"pears"}}
    ),
    res=Table.AddColumn(Product, "Fruit Upper", each ScalarVectorUpper([Fruit]))

in
    res

结果和前面常规的代码一样。不过这里数据太少,我没什么感觉,你可以自己试试。好了,我也熟悉一点了。

猜你喜欢

转载自blog.csdn.net/qq_24499417/article/details/84849137