PowerShellでインラインIf(IIf、以下も参照してください: http://en.wikipedia.org/wiki/IIf または ternary If )でステートメントを作成する方法?
これがネイティブのPowerShell関数であると考えている場合は、これに投票してください: https://connect.Microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand
PowerShellのネイティブな方法を使用できます。
"The condition is " + (&{If($Condition) {"True"} Else {"False"}}) + "."
しかし、これにより構文に多くの括弧と括弧が追加されるため、次の(おそらく最小の既存の)CmdLetを検討することができます。
Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}
これにより、コマンドが次のように簡素化されます。
"The condition is " + (IIf $Condition "True" "False") + "."
2014-09-19を追加:
私はしばらくの間IIf
コマンドレットを使用していますが、多くの場合、構文がより読みやすくなると思いますが、考えられる両方の値が明らかに1つの値でも評価されるという望ましくない副作用に関するJasonのメモに同意します使用されている、私はIIf
コマンドレットを少し変更しました:
Function IIf($If, $IfTrue, $IfFalse) {
If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}
これで、mightこの例に示すように、不要な場合は評価されないオブジェクトの代わりに、({}
'sで囲まれた)ScriptBlockを追加します。
IIf $a {1/$a} NaN
またはインラインに配置:
"The multiplicative inverse of $a is $(IIf $a {1/$a} NaN)."
$a
の値がゼロ以外の場合、乗法逆数が返されます。それ以外の場合は、NaN
を返します({1/$a}
は評価されません)。
静かなあいまいな構文を(特にインラインに配置する場合に)より単純にする別の素敵な例は、$Null
の可能性があるオブジェクトでメソッドを実行する場合です。これを行うネイティブの「If
」方法は、次のようになります。
If ($Object) {$a = $Object.Method()} Else {$a = $null}
(Else
の部分は、$a
をリセットする必要があるループなどで必要になることが多いことに注意してください。)
IIf
コマンドレットでは、次のようになります。
$a = IIf $Object {$Object.Method()}
($Object
が$Null
の場合、$a
の値が指定されていないと、$Null
は自動的に$IfFalse
に設定されます。)
2014-09-19を追加:
現在のオブジェクトを設定するIIf
コマンドレットの小さな変更( $_
または $PSItem
):
Function IIf($If, $Then, $Else) {
If ($If -IsNot "Boolean") {$_ = $If}
If ($If) {If ($Then -is "ScriptBlock") {&$Then} Else {$Then}}
Else {If ($Else -is "ScriptBlock") {&$Else} Else {$Else}}
}
これは、潜在的に$Null
になる可能性のあるオブジェクトのメソッドを使用して、ステートメント(PowerShellの方法)を単純化できることを意味します。
これの一般的な構文は$a = IIf $Object {$_.Method()}
になります。より一般的な例は次のようになります。
$VolatileEnvironment = Get-Item -ErrorAction SilentlyContinue "HKCU:\Volatile Environment"
$UserName = IIf $VolatileEnvironment {$_.GetValue("UserName")}
コマンド$VolatileEnvironment.GetValue("UserName")
は通常、 "NULL値の式ではメソッドを呼び出せません。"エラーが発生することに注意してください。関係するレジストリ(HKCU:\Volatile Environment
)は存在しません。コマンドIIf $VolatileEnvironment {$_.GetValue("UserName")}
は$Null
を返すだけです。
$If
パラメーターが条件($Number -lt 5
のようなもの)または条件([Bool]
タイプを使用)に強制される場合、IIf
コマンドレットは現在のオブジェクトを無効にしません。例:
$RegistryKeys | ForEach {
$UserName = IIf ($Number -lt 5) {$_.GetValue("UserName")}
}
または:
$RegistryKeys | ForEach {
$UserName = IIf [Bool]$VolatileEnvironment {$_.OtherMethod()}
}
'The condition is {0}.' -f ('false','true')[$condition]
実際には、Powershellは割り当てられていない値を返します
$a = if ($condition) { $true } else { $false }
例:
"The item is $(if ($price -gt 100) { 'expensive' } else { 'cheap' })"
試してみましょう:
$price = 150
The item is expensive
$price = 75
The item is cheap
別の方法を次に示します。
$condition = $false
"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
ここから: https://blogs.msdn.Microsoft.com/powershell/2006/12/29/diy-ternary-operator/
Relevant code:
# —————————————————————————
# Name: Invoke-Ternary
# Alias: ?:
# Author: Karl Prosser
# Desc: Similar to the C# ? : operator e.g.
# _name = (value != null) ? String.Empty : value;
# Usage: 1..10 | ?: {$_ -gt 5} {“Greater than 5;$_} {“Not greater than 5”;$_}
# —————————————————————————
set-alias ?: Invoke-Ternary -Option AllScope -Description “PSCX filter alias”
filter Invoke-Ternary ([scriptblock]$decider, [scriptblock]$ifTrue, [scriptblock]$ifFalse)
{
if (&$decider) {
&$ifTrue
} else {
&$ifFalse
}
}
そして、あなたはこのようにそれを使うことができます:
$total = ($quantity * $price ) * (?: {$quantity -le 10} {.9} {.75})
これは私がこれまで見た中で最も近い変種です。
Function Compare-InlineIf
{
[CmdletBinding()]
Param(
[Parameter(
position=0,
Mandatory=$false,
ValueFromPipeline=$false
)]
$Condition,
[Parameter(
position=1,
Mandatory=$false,
ValueFromPipeline=$false
)]
$IfTrue,
[Parameter(
position=2,
Mandatory=$false,
ValueFromPipeline=$false
)]
$IfFalse
)
Begin{
Function Usage
{
write-Host @"
Syntax
Compare-InlineIF [[-Condition] <test>] [[-IfTrue] <String> or <ScriptBlock>]
[[-IfFalse] <String> or <ScriptBlock>]
Inputs
None
You cannot pipe objects to this cmdlet.
Outputs
Depending on the evaluation of the condition statement, will be either the IfTrue or IfFalse suplied parameter values
Examples
.Example 1: perform Compare-InlineIf :
PS C:\>Compare-InlineIf -Condition (6 -gt 5) -IfTrue "yes" -IfFalse "no"
yes
.Example 2: perform IIF :
PS C:\>IIF (6 -gt 5) "yes" "no"
yes
.Example 3: perform IIF :
PS C:\>IIF `$object "`$true","`$false"
False
.Example 4: perform IIF :
`$object = Get-Item -ErrorAction SilentlyContinue "HKCU:\AppEvents\EventLabels\.Default\"
IIf `$object {`$_.GetValue("DispFilename")}
@mmres.dll,-5824
"@
}
}
Process{
IF($IfTrue.count -eq 2 -and -not($IfFalse)){
$IfFalse = $IfTrue[1]
$IfTrue = $IfTrue[0]
}elseif($iftrue.count -ge 3 -and -not($IfFalse)){
Usage
break
}
If ($Condition -IsNot "Boolean")
{
$_ = $Condition
} else {}
If ($Condition)
{
If ($IfTrue -is "ScriptBlock")
{
&$IfTrue
}
Else
{
$IfTrue
}
}
Else
{
If ($IfFalse -is "ScriptBlock")
{
&$IfFalse
}
Else
{
$IfFalse
}
}
}
End{}
}
Set-Alias -Name IIF -Value Compare-InlineIf