PowerShell Inline If(IIf)
(6)
Aquí hay otra manera:
$condition = $false
"The condition is $(@{$true = "true"; $false = "false"}[$condition])"
¿Cómo creo un enunciado a con Inline If (IIf, ver también: http://en.wikipedia.org/wiki/IIf o ternary If ) en PowerShell?
Si también cree que esta debería ser una función nativa de PowerShell, vote esto: https://connect.microsoft.com/PowerShell/feedback/details/1497806/iif-statement-if-shorthand
En realidad, Powershell devuelve valores que no han sido asignados
$a = if ($condition) { $true } else { $false }
Ejemplo:
"The item is $(if ($price -gt 100) { ''expensive'' } else { ''cheap'' })"
Probémoslo:
$price = 150
The item is expensive
$price = 75
The item is cheap
PowerShell no tiene soporte para ifs en línea. Tendrá que crear su propia función (como sugiere otra respuesta) o combinar declaraciones if / else en una sola línea (como también sugiere otra respuesta).
Puede usar el modo nativo de PowerShell:
"The condition is " + (&{If($Condition) {"True"} Else {"False"}}) + "."
Pero como esto agrega muchos paréntesis y corchetes a su sintaxis, puede considerar el siguiente (probablemente uno de los más pequeños) CmdLet:
Function IIf($If, $Right, $Wrong) {If ($If) {$Right} Else {$Wrong}}
Lo cual simplificará tu comando para:
"The condition is " + (IIf $Condition "True" "False") + "."
Agregado 2014-09-19:
He estado utilizando el cmdlet IIf
ahora por un tiempo y todavía creo que hará que las sintaxis sean más legibles en muchos casos, pero como estoy de acuerdo con la nota de Jason sobre el efecto secundario no deseado, se evaluarán ambos valores posibles, obviamente, solo un valor se usa, he cambiado un poco el cmdlet IIf
:
Function IIf($If, $IfTrue, $IfFalse) {
If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}
Ahora puede agregar un ScriptBlock (rodeado por {}
''s) en lugar de un objeto que no se evaluará si no se requiere, como se muestra en este ejemplo:
IIf $a {1/$a} NaN
O colocado en línea:
"The multiplicative inverse of $a is $(IIf $a {1/$a} NaN)."
En caso de que $a
tenga un valor distinto de cero, se devuelve el inverso multiplicativo; de lo contrario, devolverá NaN
(donde {1/$a}
no se evalúa).
Otro buen ejemplo en el que hará que una sintaxis ambigua y silenciosa sea mucho más simple (especialmente en el caso de que desee colocarla en línea) es donde desea ejecutar un método en un objeto que podría ser $Null
. La forma nativa de '' If
'' para hacer esto sería algo como esto:
If ($Object) {$a = $Object.Method()} Else {$a = $null}
(Tenga en cuenta que la parte Else
a menudo se requiere en, por ejemplo, bucles donde tendrá que restablecer $a
.)
Con el cmdlet IIf
se verá así:
$a = IIf $Object {$Object.Method()}
(Tenga en cuenta que si $Object
es $Null
, $a
se establecerá automáticamente en $Null
si no se proporciona $IfFalse
valor de $IfFalse
).
Agregado 2014-09-19:
Menor cambio en el cmdlet IIf
que ahora establece el objeto actual ( $_
o $_ ):
Function IIf($If, $IfTrue, $IfFalse) {
If ($If -IsNot "Boolean") {$_ = $If}
If ($If) {If ($IfTrue -is "ScriptBlock") {&$IfTrue} Else {$IfTrue}}
Else {If ($IfFalse -is "ScriptBlock") {&$IfFalse} Else {$IfFalse}}
}
Esto significa que puede simplificar una declaración (la forma de PowerShell) con un método en un objeto que podría ser $Null
.
La sintaxis general para esto ahora será $a = IIf $Object {$_.Method()}
. Un ejemplo más común se verá algo así como:
$VolatileEnvironment = Get-Item -ErrorAction SilentlyContinue "HKCU:/Volatile Environment"
$UserName = IIf $VolatileEnvironment {$_.GetValue("UserName")}
Tenga en cuenta que el comando $VolatileEnvironment.GetValue("UserName")
normalmente generará un "No se puede llamar a un método en una expresión de valor nulo". error si el registro en cuestión ( HKCU:/Volatile Environment
) no existe; donde el comando IIf $VolatileEnvironment {$_.GetValue("UserName")}
simplemente devolverá $Null
.
Si el parámetro $If
es una condición (algo así como $Number -lt 5
) o forzado a una condición (con el tipo [Bool]
), el cmdlet IIf
no anulará el objeto actual, por ejemplo:
$RegistryKeys | ForEach {
$UserName = IIf ($Number -lt 5) {$_.GetValue("UserName")}
}
O:
$RegistryKeys | ForEach {
$UserName = IIf [Bool]$VolatileEnvironment {$_.OtherMethod()}
}
''The condition is {0}.'' -f (''false'',''true'')[$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