Comment créer une instruction avec Inline If (IIf, voir aussi: http://en.wikipedia.org/wiki/IIf ou ternary If ) dans PowerShell?
Si vous pensez également que cela devrait être une fonction PowerShell native, votez sur ceci: https://connect.Microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand
Vous pouvez utiliser la méthode native de PowerShell:
"The condition is " + (&{If($Condition) {"True"} Else {"False"}}) + "."
Mais comme cela ajoute beaucoup de parenthèses et de crochets à votre syntaxe, vous pouvez envisager le suivant (probablement l’un des plus petits existants) CmdLet:
Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}
Ce qui simplifiera votre commande pour:
"The condition is " + (IIf $Condition "True" "False") + "."
Ajouté le 2014-09-19:
J'utilise la cmdlet IIf
depuis un certain temps et je pense toujours que cela rendra les syntaxes plus lisibles dans de nombreux cas, mais comme je suis d'accord avec la note de Jason concernant l'effet secondaire indésirable, les deux valeurs possibles seront évaluées, même si ce n'est qu'une valeur. est utilisé, j'ai un peu modifié la cmdlet IIf
:
Function IIf($If, $IfTrue, $IfFalse) {
If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}
Maintenant, vous pouvez ajouter un ScriptBlock (entouré de {}
) au lieu d'un objet qui ne sera pas évalué s'il n'est pas requis, comme indiqué dans cet exemple:
IIf $a {1/$a} NaN
Ou placé en ligne:
"The multiplicative inverse of $a is $(IIf $a {1/$a} NaN)."
Si $a
a une valeur autre que zéro, l'inverse multiplicatif est renvoyé; sinon, il retournera NaN
(où le {1/$a}
n'est pas évalué).
Un autre exemple intéressant qui simplifiera beaucoup la syntaxe d'une ambiguïté discrète (en particulier si vous souhaitez la placer en ligne) est l'endroit où vous souhaitez exécuter une méthode sur un objet qui pourrait potentiellement être $Null
. Le natif 'If
'. façon de le faire, serait quelque chose comme ça:
If ($Object) {$a = $Object.Method()} Else {$a = $null}
(Notez que la partie Else
est souvent requise dans des boucles, par exemple, où vous devrez réinitialiser $a
.)
Avec l'applet de commande IIf
, cela ressemblera à ceci:
$a = IIf $Object {$Object.Method()}
(Notez que si le $Object
est $Null
, $a
sera automatiquement défini sur $Null
si aucune valeur $IfFalse
n'est fournie.)
Ajouté le 2014-09-19:
Modification mineure de la cmdlet IIf
qui définit désormais l'objet actuel ( $_
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 instruction (à la manière de PowerShell) avec une méthode sur un objet pouvant potentiellement être $Null
.
La syntaxe générale pour cela sera désormais $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")
entraînera normalement un "Vous ne pouvez pas appeler une méthode sur une expression de valeur NULL." erreur si le registre concerné (HKCU:\Volatile Environment
) n’existe pas; où la commande IIf $VolatileEnvironment {$_.GetValue("UserName")}
renverra simplement $Null
.
Si le paramètre $If
est une condition (quelque chose comme $Number -lt 5
) ou forcé à une condition (avec le type [Bool]
), la cmdlet IIf
ne remplacera pas l'objet actuel, par exemple:
$RegistryKeys | ForEach {
$UserName = IIf ($Number -lt 5) {$_.GetValue("UserName")}
}
Ou:
$RegistryKeys | ForEach {
$UserName = IIf [Bool]$VolatileEnvironment {$_.OtherMethod()}
}
'The condition is {0}.' -f ('false','true')[$condition]
En fait, Powershell restitue 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-le:
$price = 150
The item is expensive
$price = 75
The item is cheap
Voici un autre moyen:
$condition = $false
"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
Cliquez ici: 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
}
}
et alors vous pouvez utiliser ça comme ça:
$total = ($quantity * $price ) * (?: {$quantity -le 10} {.9} {.75})
C'est la variante la plus proche que j'ai vue jusqu'à présent.
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