据我所知,PowerShell似乎没有用于所谓三元运算符的内置表达式。

例如,在支持三元操作符的C语言中,我可以这样写:

<condition> ? <condition-is-true> : <condition-is-false>;

如果PowerShell中没有这样的功能,那么要达到同样的效果(即易于阅读和维护),最好的方法是什么?


当前回答

由于三元操作符通常在赋值时使用,因此它应该返回一个值。这是可行的方法:

$var=@("value if false","value if true")[[byte](condition)]

愚蠢,但有效。此外,这种结构可以用于快速将int转换为另一个值,只需添加数组元素并指定一个返回基于0的非负值的表达式。

其他回答

我也在寻找一个更好的答案,虽然爱德华文章中的解决方案是“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" 

从PowerShell版本7开始,三元运算符被内置到PowerShell中。

1 -gt 2 ? "Yes" : "No"
# Returns "No"

1 -gt 2 ? 'Yes' : $null
# Get a $null response for false-y return value

如果你只是在寻找一种语法上简单的方法来基于布尔条件赋值/返回一个字符串或数字,你可以使用这样的乘法运算符:

"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博客文章,你可以创建一个别名来定义?:operator:

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})

尝试powershell的switch语句作为替代,特别是对于变量赋值-多行,但可读。

的例子,

$WinVer = switch ( Test-Path -Path "$Env:windir\SysWOW64" ) {
  $true    { "64-bit" }
  $false   { "32-bit" }
}
"This version of Windows is $WinVer"