Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ternary operator in PowerShell

People also ask

Does PowerShell have a ternary operator?

PowerShell 7.0 Beta 4 introduces a familiar mainstay of most programming languages, the Ternary Operator. Using a much shorter syntax for if/then logic, it makes defining conditional values for properties much more concise and easy to read.

What is ternary operator with example?

A ternary operator lets you assign one value to the variable if the condition is true, and another value if the condition is false. The if else block example from above could now be written as shown in the example below. var num = 4, msg = ""; msg = (num === 4) ?

What does $() mean in PowerShell?

The $() is the subexpression operator. It causes the contained expressions to be evaluated and it returns all expressions as an array (if there is more than one) or as a scalar (single value).

What does @{ mean in PowerShell?

In PowerShell V2, @ is also the Splat operator. PS> # First use it to create a hashtable of parameters: PS> $params = @{path = "c:\temp"; Recurse= $true} PS> # Then use it to SPLAT the parameters - which is to say to expand a hash table PS> # into a set of command line parameters.


$result = If ($condition) {"true"} Else {"false"}

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

write-host  $(If ($condition) {"true"} Else {"false"}) 

Powershell 7 has it. 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

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

@({'condition is false'},{'condition is true'})[$condition]

Per this PowerShell blog post, you can create an alias to define a ?: 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 
   }
}

Use it like this:

$total = ($quantity * $price ) * (?:  {$quantity -le 10} {.9} {.75})

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" 

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"