Ternary operator in PowerShell

2019-01-07 09:00发布

From what I know, PowerShell doesn't seem to have a built-in expression for the so-called ternary operator.

For example, in the C language, which supports the ternary operator, I could write something like:

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

If that doesn't really exist in PowerShell, what would be the best way (i.e. easy to read and to maintain) to accomplish the same result?

10条回答
2楼-- · 2019-01-07 09:30

Since I have used this many times already and didn't see it listed here, I'll add my piece :

$var = @{$true="this is true";$false="this is false"}[1 -eq 1]

ugliest of all !

kinda source

查看更多
成全新的幸福
3楼-- · 2019-01-07 09:31

The closest PowerShell construct I've been able to come up with to emulate that is:

@({'condition is false'},{'condition is true'})[$condition]
查看更多
4楼-- · 2019-01-07 09:31

Try powershell's switch statement as an alternative, especially for variable assignment - multiple lines, but readable.

Example,

$WinVer = switch ( Test-Path $Env:windir\SysWOW64 ) {
  $true    { "64-bit" }
  $false   { "32-bit" }
}
"This version of Windows is $WinVer"
查看更多
别忘想泡老子
5楼-- · 2019-01-07 09:36
$result = If ($condition) {"true"} Else {"false"}

Everything else is incidental complexity and thus to be avoided.

For use in or as an expression, not just an assignment, wrap it in $(), thus:

write-host  $(If ($condition) {"true"} Else {"false"}) 
查看更多
forever°为你锁心
6楼-- · 2019-01-07 09:40

I've recently improved (open PullRequest) the ternary conditional and null-coalescing operators in the PoweShell lib 'Pscx'
Pls have a look for my solution.


My github topic branch: UtilityModule_Invoke-Operators

Functions:

Invoke-Ternary
Invoke-TernaryAsPipe
Invoke-NullCoalescing
NullCoalescingAsPipe

Aliases

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"

Usage

<condition_expression> |?: <true_expression> <false_expression>

<variable_expression> |?? <alternate_expression>

As expression you can pass:
$null, a literal, a variable, an 'external' expression ($b -eq 4) or a scriptblock {$b -eq 4}

If a variable in the variable expression is $null or not existing, the alternate expression is evaluated as output.

查看更多
【Aperson】
7楼-- · 2019-01-07 09:41

I too, looked for a better answer, and while the solution in Edward's post is "ok", I came up with a far more natural solution in this blog post

Short and sweet:

# ---------------------------------------------------------------------------
# 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."

Which makes it easy to do stuff like (more examples in blog post):

$message == ($age > 50) ? "Old Man" :"Young Dude" 
查看更多
登录 后发表回答