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
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()}
}
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]
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
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])"
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
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ź).
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