PowerShell Inline Si (IIf)
comment créer une déclaration avec un Inline If (IIf, voir aussi: http://en.wikipedia.org/wiki/IIf ou ternaire si ) dans PowerShell?
si vous pensez aussi que cela devrait être une fonction de PowerShell native, s'il vous plaît votez ceci: https://connect.microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand
6 réponses
, Vous pouvez utiliser le PowerShell natif de l':
"The condition is " + (&{If($Condition) {"True"} Else {"False"}}) + "."
mais comme ceci ajoute beaucoup de parenthèses et de crochets à votre syntaxe, vous pourriez considérer le CmdLet suivant (probablement l'un des plus petits existant):
Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}
qui simplifiera votre commande à:
"The condition is " + (IIf $Condition "True" "False") + "."
ajouté 2014-09-19:
j'ai utilisé le IIf
applet de commande pendant un certain temps maintenant et je pense toujours qu'il va faire des syntaxes plus lisible dans beaucoup de cas, mais comme je suis d'accord avec Jason remarque à propos de l'effet indésirable que les deux valeurs possibles seront évaluées de même, évidemment, une seule valeur est utilisée, j'ai changé le IIf
applet de commande un peu:
Function IIf($If, $IfTrue, $IfFalse) {
If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}
Maintenant, vous pourrait ajouter un ScriptBlock ("entouré de 1519140920") au lieu d'un objet qui ne sera pas évalué si c'est non requis comme indiqué dans cet exemple:
IIf $a {1/$a} NaN
Ou mis en ligne:
"The multiplicative inverse of $a is $(IIf $a {1/$a} NaN)."
dans le cas $a
a une valeur autre que zéro, l'inverse multiplicatif est retourné; sinon, il retournera NaN
(où le {1/$a}
n'est pas évalué).
un autre bel exemple où il va faire une syntaxe ambiguë calme beaucoup plus simple (surtout dans le cas où vous voulez le placer en ligne) est où vous voulez pour exécuter une méthode sur un objet qui pourrait être $Null
.
La ‘ If
’ façon de faire quelque chose, serait quelque chose comme ceci:
If ($Object) {$a = $Object.Method()} Else {$a = $null}
(notez que la partie Else
est souvent nécessaire dans les boucles par exemple où vous devrez réinitialiser $a
.)
avec le cmdlet IIf
il ressemblera à ceci:
$a = IIf $Object {$Object.Method()}
(notez que si le $Object
est $Null
, $a
sera automatiquement réglé sur $Null
si aucune valeur $IfFalse
n'est fournie.)
ajouté 2014-09-19:
changement mineur au cmdlet IIf
qui définit maintenant l'objet courant( $_
ou $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}}
}
cela signifie que vous pouvez simplifier une déclaration (la manière PowerShell) avec un méthode sur un objet qui pourrait potentiellement être $Null
.
la syntaxe générale pour cela sera maintenant $a = IIf $Object {$_.Method()}
. Un exemple plus courant ressemblera à quelque chose comme:
$VolatileEnvironment = Get-Item -ErrorAction SilentlyContinue "HKCU:\Volatile Environment"
$UserName = IIf $VolatileEnvironment {$_.GetValue("UserName")}
notez que la commande $VolatileEnvironment.GetValue("UserName")
résultera normalement en un " vous ne pouvez pas appeler une méthode sur une expression à valeur nulle." erreur si le registre concerné ( HKCU:\Volatile Environment
) n'existe pas; où la commande IIf $VolatileEnvironment {$_.GetValue("UserName")}
sera juste retournez $Null
.
si le paramètre $If
est une condition (quelque chose comme $Number -lt 5
) ou forcée à une condition( avec le type [Bool]
), le cmdlet IIf
n'annulera pas l'objet courant, par exemple:
$RegistryKeys | ForEach {
$UserName = IIf ($Number -lt 5) {$_.GetValue("UserName")}
}
ou:
$RegistryKeys | ForEach {
$UserName = IIf [Bool]$VolatileEnvironment {$_.OtherMethod()}
}
en fait Powershell donne des valeurs qui n'ont pas été attribuées
$a = if ($condition) { $true } else { $false }
exemple:
"The item is $(if ($price -gt 100) { 'expensive' } else { 'cheap' })"
essayons ceci:
$price = 150
The item is expensive
$price = 75
The item is cheap
Voici une autre façon:
$condition = $false
"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
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
PowerShell n'a pas de support pour les ifs inline. Vous devrez créer votre propre fonction (comme une autre réponse le suggère), ou combiner les énoncés if/else sur une seule ligne (comme une autre réponse le suggère également).