Ternary operator in PowerShell

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

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

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

If this really does not exist in PowerShell, what would be the best way (i.e. easy to read and maintain) to achieve the same result?

+170
ternary-operator conditional-operator powershell
Jul 10 '15 at 13:26
source share
8 answers
 $result = If ($condition) {"true"} Else {"false"} 

Everything else is random complexity and therefore should be avoided.

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

 write-host $(If ($condition) {"true"} Else {"false"}) 
+261
Dec 16 '15 at 11:44
source share

The closest Powershell construct I could emulate is:

 . ({'condition is false'},{'condition is true'})[$condition] 
+50
Jul 10 '15 at 13:52
source share

In this PowerShell blog post, you can create an alias to define the ?: 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 as follows:

 $total = ($quantity * $price ) * (?: {$quantity -le 10} {.9} {.75}) 
+24
Nov 12 '15 at 13:01
source share

I was also looking for a better answer, and although the solution as Edward is “normal”, I came up with a much 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> # eg # status = (age > 50) ? "old" : "young"; # Null-Coalescing # <value> ?? <value-if-value-is-null> # eg # 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 Invoke-Assignment." 

Which makes it easy to do such things (more blog examples):

 $message == ($age > 50) ? "Old Man" :"Young Dude" 
+20
Dec 11 '15 at 19:21
source share

Since the ternary operator is usually used when assigning a value, it should return a value. This is the way of working:

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

Stupid, but it works. You can also use this construct to quickly turn an int into another value, just add the elements of the array and specify an expression that returns 0-based non-negative values.

+9
Jul 10 '15 at 14:16
source share

Since I have used this many times and have not seen it here, I will add my part:

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

ugliest of all!

native source

+4
Sep 16 '15 at 18:44
source share

 IIf <condition> <condition-is-true> <condition-is-false> 
See: PowerShell Inline If (IIf)
+4
Jul 22 '17 at 10:52
source share

Here's an alternative approach to custom functions:

 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' 

Example

 1 -eq 1 |??? 'match' : 'nomatch' 1 -eq 2 |??? 'match' : 'nomatch' 

Differences Explained

  • Why are these 3 question marks instead of 1?
    • Symbol ? is already an alias for Where-Object .
    • ?? used in other languages ​​as an operator of zero coalescence, and I wanted to avoid confusion.
  • Why do we need a pipe in front of the team?
    • Since I use the pipeline to evaluate this, we still need this symbol to pass the condition to our function
  • What happens if I go through an array?
    • We get a result for each value; those. -2..2 |??? 'match' : 'nomatch' -2..2 |??? 'match' : 'nomatch' gives: match, match, nomatch, match, match (i.e. since any non-zero int evaluates true , and zero evaluates to false ).
    • If you do not want this, convert the array to bool; ([bool](-2..2)) |??? 'match' : 'nomatch' ([bool](-2..2)) |??? 'match' : 'nomatch' (or simply: [bool](-2..2) |??? 'match' : 'nomatch' )
+1
Jun 13 '17 at 16:38 on
source share



All Articles