ときおり出てくる "each"  キーワードと "_" (アンダースコア) とは

Power BI Desktop や Excel のクエリ エディターでデータの変換や加工をしていると、"each" キーワードと "_"(アンダースコア)が 式に使用されている。さて、これは何か？というお話。クエリ エディターで生成された Power Query(M言語)を理解し、もっと複雑な処理(適用するステップ)をしたい場合には必要なことなので。

ボタンポチポチだけの作業で済むのなら気にすることはないけれども。

# どのように使われているか
例えば、[Table.AddColumn 関数 - Power Query M function reference][Table.AddColumn]

```text:構文：Table.AddColumn(M)
Table.AddColumn(
    table as table,
    newColumnName as text,
    columnGenerator as function, // <--- ここで使用されている
    optional columnType as nullable type
) as table
```
テーブルに列を追加するとき、その追加列の値を 関数型( type function )の引数 : columnGenerator で指定している。

"テーブル" に対し "追加列" という列を追加し、その値をそれぞれ 0 にするというステップでは、"each" がでてくる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/55fe51b0-332c-7f00-65aa-b0f7686b169b.png)

```text:列の追加(テーブル)
Table.AddColumn( テーブル, "追加列", each 0 )
```

テーブル から空白行を除外するステップを適用するとき、"each" と "_"(アンダースコア) が使われている。

```text:空白行の削除(テーブル)
Table.SelectRows(
    PreviousStep_table,
    each not List.IsEmpty(
        List.RemoveMatchingItems(
            Record.FieldValues(_),
            {"", null}
        )
    )
)
```
# "each" キーワード と "_"(アンダースコア)
"each" と "\_"(アンダースコア) はセットで使用するが、"_"(アンダースコア) は省略されることがある。

## each
そのまんまの意味で each です。"それぞれ" と考えてよさそう。

- リスト(list)を扱う関数の場合、リストのアイテム(item)それぞれに処理を行う
- テーブル(table)を扱う関数の場合、行(row)それぞれに処理を行う

## "_"(アンダースコア)
### リスト ( list )
```text:リストアイテムそれぞれに加算(+1)
List.Transform( {1, 2, 3}, each _ + 1 ) = {2, 3, 4} // true
```
```text:構文：List.Transform(M)
List.Transform(
    list as list,
    transform as function
)  as list
```
each _ + 1 の "_"(アンダースコア)は、リストアイテムそれぞれを処理するときそのアイテムを表す変数名。

### テーブル ( table )

```text:テーブルから特定の列を除外
Table.SelectRows( テーブル , each [列1] > 3)
```

```text:構文：Table.SelectRows(M)
Table.SelectRows(
    table as table,
    condition as function
) as table
```
ここには "_"(アンダースコア)がない。これは速記簡略されていると考えればよくて、

```text:テーブルから特定の列を除外
Table.SelectRows( テーブル , each _[列1] > 3 )
```

each \_[列1] > 3 の "_"(アンダースコア)は、テーブル各行でそれぞれを処理するときその行を表す変数名。
そして、そのデータ型は record に特定。なので、フィールドをルックアップする記述は、"[ ]"(ブラケット)を使って _[ *column-name* ]

```text:取りうる値はレコード型
let
    Source = #table(
        type table [列1 = any, 列2 = any],
        {
            {"A", 1}, {"A", 2}, {"B", 3}, {"B", 4}
        }
    ),
    AddedCustom = Table.AddColumn(
        Source,
        "IsType.Record",
        each Type.Is( Value.Type( _ ), Record.Type ) )
in
    AddedCustom
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/193509/852071f7-2286-8c46-f4e2-4fec8b9b8f12.png)


## shorthand
Power Query での関数の記述は、(x) => x + 10 という感じなのだけど、テーブルやリスト扱う関数では 速記簡略する記述が可能なことが多い。そして中の人は多く使っている。

```text:極端な例
let
    Source = #table(
        type table [列1 = any, 列2 = any],
        {
            {"A", 1}, {"A", 2}, {"B", 3}, {"B", 4}
        }
    ),
    TrimmedText = Table.TransformColumns( Source, { "列1", Text.Trim } ) // ココ、トッテモ shorthand
in
    TrimmedText
```

変換対象の値がひとつに特定でき、かつ、変換関数の必須引数がひとつなのでとてもシンプルな記述になっているわけで、
Table.TransformColumns( Source, { "列1", **each Text.Trim( _ )** } )
とも記述できるし、
Table.TransformColumns( Source, { "列1", **( CurrentString ) => Text.Trim( CurrentString )** } )
とも記述できる。

変換関数の必須の引数が複数になるときや、オプション引数にも値を渡す場合には、"each" キーワード と "_"(アンダースコア) を使用することになるんですけど。


# その他
- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)

[Table.AddColumn]:https://msdn.microsoft.com/en-us/library/mt260727.aspx
[List.Transform]:https://msdn.microsoft.com/en-us/library/mt253641.aspx
[Table.SelectRows]:https://msdn.microsoft.com/en-us/library/mt260810.aspx