据我所知,PowerShell似乎没有所谓的三元运算符的内置表达式。
例如,在支持三元操作符的C语言中,我可以这样写:
<condition> ? <condition-is-true> : <condition-is-false>;
如果PowerShell中没有这样的功能,那么要达到同样的效果(即易于阅读和维护),最好的方法是什么?
我能够想出的最接近PowerShell的构造是:
@({'condition is false'},{'condition is true'})[$condition]
由于三元操作符通常在赋值时使用,因此它应该返回一个值。这是可行的方法:
$var=@("value if false","value if true")[[byte](condition)]
愚蠢,但有效。此外,这种结构可以用于快速将int转换为另一个值,只需添加数组元素并指定一个返回基于0的非负值的表达式。
因为我已经用过很多次了,没有看到它列在这里,我将添加我的部分:
$var = @{$true="this is true";$false="this is false"}[1 -eq 1]
最丑的!
kinda source
根据这个PowerShell博客文章,你可以创建一个别名来定义?:操作符:
?:
set-alias ?: Invoke-Ternary -Option AllScope -Description "PSCX filter alias" filter Invoke-Ternary ([scriptblock]$decider, [scriptblock]$ifTrue, [scriptblock]$ifFalse) { if (&$decider) { &$ifTrue } else { &$ifFalse } }
像这样使用它:
$total = ($quantity * $price ) * (?: {$quantity -le 10} {.9} {.75})
我也在寻找一个更好的答案,虽然爱德华的帖子中的解决方案是“ok”,但我想出了一个更自然的解决方案在这篇博文中
简短而甜蜜:
# --------------------------------------------------------------------------- # Name: Invoke-Assignment # Alias: = # Author: Garrett Serack (@FearTheCowboy) # Desc: Enables expressions like the C# operators: # Ternary: # <condition> ? <trueresult> : <falseresult> # e.g. # status = (age > 50) ? "old" : "young"; # Null-Coalescing # <value> ?? <value-if-value-is-null> # e.g. # name = GetName() ?? "No Name"; # # Ternary Usage: # $status == ($age > 50) ? "old" : "young" # # Null Coalescing Usage: # $name = (get-name) ? "No Name" # --------------------------------------------------------------------------- # returns the evaluated value of the parameter passed in, # executing it, if it is a scriptblock function eval($item) { if( $item -ne $null ) { if( $item -is "ScriptBlock" ) { return & $item } return $item } return $null } # an extended assignment function; implements logic for Ternarys and Null-Coalescing expressions function Invoke-Assignment { if( $args ) { # ternary if ($p = [array]::IndexOf($args,'?' )+1) { if (eval($args[0])) { return eval($args[$p]) } return eval($args[([array]::IndexOf($args,':',$p))+1]) } # null-coalescing if ($p = ([array]::IndexOf($args,'??',$p)+1)) { if ($result = eval($args[0])) { return $result } return eval($args[$p]) } # neither ternary or null-coalescing, just a value return eval($args[0]) } return $null } # alias the function to the equals sign (which doesn't impede the normal use of = ) set-alias = Invoke-Assignment -Option AllScope -Description "FearTheCowboy's Invoke-Assignment."
这样就可以很容易地做一些事情,比如(更多的例子在博客文章中):
$message == ($age > 50) ? "Old Man" :"Young Dude"
$result = If ($condition) {"true"} Else {"false"}
要在表达式中使用或作为表达式使用,而不仅仅是赋值,请将其包装在$()中,这样:
$()
write-host $(If ($condition) {"true"} Else {"false"})
下面是另一种自定义函数方法:
function Test-TernaryOperatorCondition { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true, Mandatory = $true)] [bool]$ConditionResult , [Parameter(Mandatory = $true, Position = 0)] [PSObject]$ValueIfTrue , [Parameter(Mandatory = $true, Position = 1)] [ValidateSet(':')] [char]$Colon , [Parameter(Mandatory = $true, Position = 2)] [PSObject]$ValueIfFalse ) process { if ($ConditionResult) { $ValueIfTrue } else { $ValueIfFalse } } } set-alias -Name '???' -Value 'Test-TernaryOperatorCondition'
例子
1 -eq 1 |??? 'match' : 'nomatch' 1 -eq 2 |??? 'match' : 'nomatch'
差异的解释
?
Where-Object
??
-2..2 |??? 'match' : 'nomatch'
match, match, nomatch, match, match
true
false
([bool](-2..2)) |??? 'match' : 'nomatch'
[bool](-2..2) |??? 'match' : 'nomatch'
PowerShell 目前不 <强> < / >强不有一个原生的内联如果(或三元如果),但你可以考虑使用自定义cmdlet:
IIf <condition> <condition-is-true> <condition-is-false>
看:PowerShell内联If (IIf)
尝试powershell的开关语句作为替代,特别是对于变量赋值-多行,但可读。
的例子,
$WinVer = switch ( Test-Path "$Env:windir\SysWOW64" ) { $true { "64-bit" } $false { "32-bit" } } "This version of Windows is $WinVer"
Invoke-Ternary Invoke-TernaryAsPipe Invoke-NullCoalescing NullCoalescingAsPipe
Set-Alias :?: Pscx\Invoke-Ternary -Description "PSCX alias" Set-Alias ?: Pscx\Invoke-TernaryAsPipe -Description "PSCX alias" Set-Alias :?? Pscx\Invoke-NullCoalescing -Description "PSCX alias" Set-Alias ?? Pscx\Invoke-NullCoalescingAsPipe -Description "PSCX alias"
<condition_expression> |?: <true_expression> <false_expression> <variable_expression> |?? <alternate_expression>
作为表达式,您可以传递: $null,一个文字,一个变量,一个“外部”表达式($b -eq 4)或一个脚本块{$b -eq 4} 如果变量表达式中的变量为$null或不存在,则替代表达式将作为输出计算
Powershell 7有这个功能。https://toastit.dev/2019/09/25/ternary-operator-powershell-7/
PS C:\Users\js> 0 ? 'yes' : 'no' no PS C:\Users\js> 1 ? 'yes' : 'no' yes
如果你只是在寻找一种语法上简单的方法来基于布尔条件赋值/返回一个字符串或数字,你可以使用这样的乘法运算符:
"Condition is "+("true"*$condition)+("false"*!$condition) (12.34*$condition)+(56.78*!$condition)
如果你只对正确的结果感兴趣,你可以完全忽略错误的部分(反之亦然),例如一个简单的评分系统:
$isTall = $true $isDark = $false $isHandsome = $true $score = (2*$isTall)+(4*$isDark)+(10*$isHandsome) "Score = $score" # or # "Score = $((2*$isTall)+(4*$isDark)+(10*$isHandsome))"
注意,布尔值不应该是乘法运算中的前项,即$condition*"true"等将不起作用。
从PowerShell版本7开始,三元运算符被内置到PowerShell中。
1 -gt 2 ? "Yes" : "No" # Returns "No" 1 -gt 2 ? 'Yes' : $null # Get a $null response for false-y return value
PowerShell中的三元运算符是在PowerShell version7.0中引入的。
[Condition] ? (output if True) : (output if False)
例01
$a = 5; $b = 6 ($a -gt $b) ? "True" : "False"
输出
False
例子02
($a -gt $b) ? ("$a is greater than $b") : ("$a is less than $b")
5 is less than 6