しばたテックブログ

PowerShellを中心に気分で書いている技術ブログです。

PowerShellの三項演算子について

あまりにも今更なはなしなのですが、根強い需要があるみたいなのでざっくりブログに書いておきます。

PowerShellの三項演算子

はじめに結論を書いておくと、現在、PowerShellに三項演算子はありません。
PowerShell 1.0 ~ PowerShell Core 6.0に至るまでどのバージョンでもサポートされていません。

ただ、三項演算子に対する要望はPowerShellがリリースされた当初からあった様で、オープンソース化した現在も以下のIssueで要望と提案がなされています。

github.com

私自身は三項演算子に対する思い入れは全くないので気にしていませんが、気になる方はこちらのIssueに積極的に参加していくと良いでしょう。

三項演算子の代わりになるもの

で、これで終わってしまうとあまりにも芸がないので三項演算子の代わりになる方法をいくつか紹介します。

1. if文

一般的なプログラミング言語に慣れている方には受け入れ難い動作かもしれませんが、PowerShell 2.0からif文が値を返す動作をします。

このため、

$result = if($condition){ Write-Output "True" }else{ Write-Output "False" }

の様な記述を三項演算子の代わりに使うことができます。
なお、式の中でこれを使いたい場合は、

"Result is " + $(if($condition){ Write-Output "True" }else{ Write-Output "False" })

の様に部分式($())にしてやればOKです。

イメージとしてはVB.NETのif演算子が近いでしょうか。


余談ですが、PowerShellにおける文と式の曖昧さ、そしてパイプライン文については牟田口先生のこちらの考察をご覧ください。必見です。

winscript.jp

2. 2値配列

ショートコーディングのテクニックの一つなのですが配列で三項演算子を代用することができます。

スクリプト中で使うことはあまりお勧めしませんがちょっとしたワンライナーを書くときのテクニックとして覚えておいて損はないかと思います。

以下の様に2値の配列にTrue、Falseごとの処理を記述し、配列の要素指定に条件を記述します。

$result = &({ Write-Output "True" }, { Write-Output "False" })[!$condition]

[int]$false = 0[int]$true = 1と暗黙的に型変換されることを利用してそれぞれの条件を実行するテクニックです。

3. Invoke-Ternary

最初に触れたPowerShell Team Blogの記事からの引用です。

# 定義
filter Invoke-Ternary ([scriptblock]$decider, [scriptblock]$ifTrue, [scriptblock]$ifFalse) 
{
    if (& $decider) { 
        & $ifTrue
    } else { 
        & $ifFalse 
    }
}
Set-Alias ?: Invoke-Ternary -Option AllScope -Description "PSCX filter alias"

# 使用例
1..10 | ?: {$_ -gt 5} {"Greater than 5";$_} {"Not greater than 5";$_}

関数やフィルターを作ってしまうならコレにこだわらず自分の好きな様に作ってしまうのが良いでしょう。

最後に

ほかにも色々なやり方で三項演算子を代用することができると思いますが本エントリではこのくらいにしておきます。