据我所知,PowerShell似乎没有所谓的ternary operator的内置表达式。
例如,在支持三元运算符的C语言中,我可以编写如下内容:
<condition> ? <condition-is-true> : <condition-is-false>;
如果在PowerShell中确实不存在,那么实现相同结果的最佳方法(即易于阅读和维护)是什么?
答案 0 :(得分:228)
$result = If ($condition) {"true"} Else {"false"}
其他一切都是偶然的复杂性,因此应该避免。
用于或作为表达,而不仅仅是作业,将其包装在$()
中,因此:
write-host $(If ($condition) {"true"} Else {"false"})
答案 1 :(得分:43)
我能够提出的最接近的PowerShell构造是:
@({'condition is false'},{'condition is true'})[$condition]
答案 2 :(得分:24)
根据此PowerShell blog post,您可以创建别名来定义?:
运算符:
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})
答案 3 :(得分:20)
我也是,寻找更好的答案,虽然爱德华的帖子中的解决方案是“好的”,但我想出了一个更自然的solution in this blog post
短而甜蜜:
# ---------------------------------------------------------------------------
# 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"
答案 4 :(得分:14)
从PowerShell版本7开始,PowerShell内置了三元运算符。
1 -gt 2 ? "Yes" : "No"
# Returns "No"
1 -gt 2 ? 'Yes' : $null
# Get a $null response for false-y return value
答案 5 :(得分:9)
由于在分配值时通常使用三元运算符,因此它应返回一个值。这是可行的方式:
$var=@("value if false","value if true")[[byte](condition)]
愚蠢,但工作。此结构也可用于快速将int转换为另一个值,只需添加数组元素并指定一个返回基于0的非负值的表达式。
答案 6 :(得分:9)
尝试使用powershell的开关语句作为替代方案,尤其是对于变量赋值 - 多行,但可读。
实施例,
$WinVer = switch ( Test-Path $Env:windir\SysWOW64 ) {
$true { "64-bit" }
$false { "32-bit" }
}
"This version of Windows is $WinVer"
答案 7 :(得分:5)
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
答案 8 :(得分:4)
由于我已经多次使用过这个并没有在此处列出,我将添加我的文章:
$var = @{$true="this is true";$false="this is false"}[1 -eq 1]
最丑陋的!
答案 9 :(得分:3)
PowerShell目前没有原生Inline If(或ternary If),但您可以考虑使用自定义cmdlet:
IIf <condition> <condition-is-true> <condition-is-false>
请参阅:PowerShell Inline If (IIf)
答案 10 :(得分:3)
我最近改进了(打开PullRequest)PoweShell lib'Pscx'中的三元条件和零合并运算符 请看看我的解决方案。
我的github主题分支: UtilityModule_Invoke-Operators
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)或scriptblock {$ b -eq 4}
如果变量表达式中的变量为$ null或不存在,则将替代表达式计算为输出。
答案 11 :(得分:1)
如果您只是在寻找一种基于布尔条件分配/返回字符串或数字的语法上简单的方法,则可以使用乘法运算符,如下所示:
"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”等不起作用。
答案 12 :(得分:1)
PowerShell 7.0 版中引入了 PowerShell 中的三元运算符。
[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
更多信息 https://www.tutorialspoint.com/how-ternary-operator-in-powershell-works
答案 13 :(得分:0)
这是另一种自定义函数方法:
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
(即因为任何非零的int评估为true
;而零评估为false
)。([bool](-2..2)) |??? 'match' : 'nomatch'
(或简称:[bool](-2..2) |??? 'match' : 'nomatch'
)