PowerShell Inline If (IIf)

Jak utworzyć instrukcję A Z Inline If (IIF, Zobacz także: http://en.wikipedia.org/wiki/IIf lub ternary If ) w PowerShell?

Jeśli uważasz, że powinna to być natywna funkcja PowerShell, zagłosuj na to: https://connect.microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand

Author: iRon, 2014-09-05

6 answers

Możesz użyć natywnej metody PowerShella:]}

"The condition is " + (&{If($Condition) {"True"} Else {"False"}}) + "."

Ale ponieważ dodaje to wiele nawiasów i nawiasów do składni, możesz rozważyć następujący (prawdopodobnie jeden z najmniejszych istniejących) CmdLet:

Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}

Które uprości twoje polecenie do:

"The condition is " + (IIf $Condition "True" "False") + "."

Dodano 2014-09-19:

Od jakiegoś czasu używam cmdleta IIf i nadal uważam, że w wielu przypadkach poprawi to czytelność składni, ale jak się Zgadzam z notką Jasona o niechcianym efekcie ubocznym, że obie możliwe wartości będą oceniane nawet oczywiście tylko jedna wartość jest używana, zmieniłem cmdlet IIf bit:

Function IIf($If, $IfTrue, $IfFalse) {
    If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
    Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}

Teraz możesz dodać blok skryptów (otoczony przez {}) zamiast obiektu, który nie będzie oceniany, jeśli nie jest wymagany, jak pokazano w tym przykładzie:

IIf $a {1/$a} NaN

Lub umieszczone w linii:

"The multiplicative inverse of $a is $(IIf $a {1/$a} NaN)."

W przypadku, gdy $a ma wartość inną niż zero, zwracana jest odwrotność multiplikatywna; w przeciwnym razie zwróci NaN (gdzie {1/$a} nie jest oceniana).

Innym miłym przykładem, w którym będzie to o wiele prostsze (szczególnie w przypadku, gdy chcesz umieścić ją w linii), jest miejsce, w którym chcesz uruchomić metodę na obiekcie, który potencjalnie może być $Null. W przeciwieństwie do tego, w jaki sposób można to zrobić, można to zrobić w następujący sposób:]}

If ($Object) {$a = $Object.Method()} Else {$a = $null}

(zauważ, że część Else jest często wymagana np. w pętlach, gdzie trzeba będzie zresetować $a.)

Z IIf cmdlet będzie to wyglądało tak:

$a = IIf $Object {$Object.Method()}

(zauważ, że jeśli $Object jest $Null, $a zostanie automatycznie ustawiona na $Null, Jeśli nie podano wartości $IfFalse.)


Dodano 2014-09-19:

Drobna zmiana na IIf cmdlet, który teraz ustawia bieżący obiekt ($_ lub $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}}
}

Oznacza to, że można uprościć instrukcję (sposób PowerShell) za pomocą metody na obiekcie, który potencjalnie może być $Null.

Ogólne składnia będzie teraz $a = IIf $Object {$_.Method()}. Bardziej powszechny przykład będzie wyglądał mniej więcej tak:

$VolatileEnvironment = Get-Item -ErrorAction SilentlyContinue "HKCU:\Volatile Environment"
$UserName = IIf $VolatileEnvironment {$_.GetValue("UserName")}

Zauważ, że polecenie $VolatileEnvironment.GetValue("UserName") Zwykle spowoduje "nie można wywołać metody na wyrażeniu o wartości null." błąd, jeśli dany rejestr (HKCU:\Volatile Environment) nie istnieje; gdzie polecenie IIf $VolatileEnvironment {$_.GetValue("UserName")} zwróci po prostu $Null.

Jeśli parametr $If jest warunkiem (coś w rodzaju $Number -lt 5) lub wymuszonym warunkiem (z typem [Bool]), to cmdlet IIf nie unieważni aktualny obiekt, np.:

$RegistryKeys | ForEach {
    $UserName = IIf ($Number -lt 5) {$_.GetValue("UserName")}
}

Lub:

$RegistryKeys | ForEach {
    $UserName = IIf [Bool]$VolatileEnvironment {$_.OtherMethod()}
}
 60
Author: iRon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-06 11:22:37
'The condition is {0}.' -f ('false','true')[$condition]
 21
Author: mjolinor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 10:19:41

W rzeczywistości Powershell zwraca wartości, które nie zostały przypisane

$a = if ($condition) { $true } else { $false }

Przykład:

"The item is $(if ($price -gt 100) { 'expensive' } else { 'cheap' })"

Spróbujmy:

$price = 150
The item is expensive
$price = 75
The item is cheap
 12
Author: Ivan Akcheurov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-05-01 06:40:55

Oto inny sposób:

$condition = $false

"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
 3
Author: ojk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 09:23:35
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
Author: HeyNow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-09 16:54:07

PowerShell nie ma wsparcia dla Wbudowanych ifs. Będziesz musiał utworzyć własną funkcję (jak sugeruje inna odpowiedź) lub połączyć polecenia if / else w jednej linii(jak sugeruje również inna odpowiedź).

 -3
Author: Aaron Jensen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-05 21:58:55