web-dev-qa-db-ja.com

PowerShellインラインIf(IIf)

PowerShellでインラインIf(IIf、以下も参照してください: http://en.wikipedia.org/wiki/IIf または ternary If )でステートメントを作成する方法?

これがネイティブのPowerShell関数であると考えている場合は、これに投票してください: https://connect.Microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand

46
iRon

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()}
}
74
iRon
'The condition is {0}.' -f ('false','true')[$condition]
27
mjolinor

実際には、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
20
Ivan Akcheurov

別の方法を次に示します。

$condition = $false

"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
4
ojk

ここから: 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})

これは私がこれまで見た中で最も近い変種です。

0
Michael Hafner
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  
0
HeyNow