📖

Power Query使いのためのF#ショーケース

2024/05/26に公開

基本的な構文

Power Query
let
   Variablename = 1 + 2,
   #"Variable name" = "abc"
in
   Variablename // 3
F#
let Variablename = 1 + 2
let ``Variable name`` = "abc"
Variablename // val it: int = 3

この例だとわかりにくいのですが、大きく異なるところとして、F#はオフサイドルールを採用しています。カンマが要らない代わりに、インデントは見た目だけではなく、ルールとして揃える必要があります。

テーブルの生成と加工

これを

Name Ext Kind Size
Alice .ai fig 171.9
Bob .BMP fig 215.0
Carol .cs code 160.0

こう

Filename Kind Size
Alice.ai fig 171.9
Bob.bmp fig 215.0
  • Kindが"fig"の行を選択する
  • Extを小文字にしたうえで、Nameと連結し、Filenameとする
Power Query
let
    Source =
        #table(
            {"Name", "Ext", "Kind", "Size"},  
            {{"Alice", ".ai", "fig", 171.9},
             {"Bob", ".BMP", "fig", 215.0},
             {"Carol", ".cs", "code", 160.0}}
        ),
    #"Filtered Rows" = Table.SelectRows(Source, each ([Kind] = "fig")),
    #"Lowercased Text" =
        Table.TransformColumns(
            #"Filtered Rows",
            {{"Ext", Text.Lower, type text}}
        ),
    #"Merged Columns" =
        Table.CombineColumns(
            #"Lowercased Text",
            {"Name", "Ext"},
            Combiner.CombineTextByDelimiter("", QuoteStyle.None),
            "Filename"
        )
in
    #"Merged Columns"
F#
let source = [
    {| Name = "Alice"; Ext = ".ai"; Kind = "fig"; Size = 171.9 |}
    {| Name = "Bob"; Ext = ".BMP"; Kind = "fig"; Size = 215.0 |}
    {| Name = "Carol"; Ext = ".cs"; Kind = "code"; Size = 160.0 |}
]

let processed =
    source
    |> List.where (_.Kind >> (=) "fig")
    |> List.map (fun x -> {|
        Filename = $"{x.Name}{x.Ext.ToLower()}"
        Kind = x.Kind
        Size = x.Size
    |})

Power Queryのように直接テーブルを表現する型はないので、ここではレコードのリストで表現しています。また、パイプライン演算子|>により、各処理に名前をつけずに簡潔に記述することができます。

関数

Power Query
let
   add = (x, y) => x + y
in
   add(1, 2) // 3
F#
let add (x, y) = x + y
add (1, 2) // val it: int = 3

カリー化

Power Query
let
   add = (x) => (y) => x + y
in
   add(1)(2)
F#
let add x y = x + y
add 1 2

部分適用

Power Query
let
   add = (x) => (y) => x + y,
   addOne = add(1)
in
   addOne(2)
F#
let add x y = x + y
let addOne = add 1
addOne 2

FizzBuzz

Power Query
let
    fizzBuzz = (i) =>
    let
        mod3 = Number.Mod(i, 3),
        mod5 = Number.Mod(i, 5)
    in
        if mod3 = 0 and mod5 = 0 then "FizzBuzz"
        else if mod3 = 0 then "Fizz"
        else if mod5 = 0 then "Buzz"
        else Text.From(i)
in
    fizzBuzz
F#
let fizzBuzz i =
    match i % 3, i % 5 with
    | 0, 0 -> "FizzBuzz"
    | 0, _ -> "Fizz"
    | _, 0 -> "Buzz"
    | _ -> i.ToString()

パターンマッチという、ざっくりいうと「超つよいswitch式のようなもの」があります。

Discussion