2

I have a question towards ternary operators in Powershell 5.1. It doesn't work as I expected it if I try to assign an array @(...):

    # I can assign an array to a variable:
    $a=@("TRUE")
    write-host "a:" $a
    
    # I can do that in a proper if/then statement, too:
    $b = @(if ($false) {@("True")} else {@("False")})
    write-host "b:" $b
    
    # Assignment of string constants works fine with ternary syntax:
    $c = @( {"True"} , {"False"} )[!$true]
    write-host "c:" $c
    
    # but not with array assignments:
    $d = @( {@("True")} , {@("False")} )[!$false]
    write-host "d:" $d
    # Expected: "False". 
    # Actual output: @("False")

Output:

a: TRUE
b: False
c: "True"
d: @("False")

A thread regarding ternary operators doesn't clarify this for me. (Ternary operator in PowerShell)

Update: $d needs to be an array, as well as the two inner items. Here they were shown with just one string constant for simplicity.

1 Answer 1

3

Note:

  • PowerShell (Core) 7+ now has a built-in ternary operator, so that you could use something like $var = $true ? "True" : "False"

Do not use { ... } around your operands: { ... } is used for script-block literals, which evaluate to their verbatim content (without the delimiters) in a string context.

Omitting the enclosing { and } solves the immediate problem:

$d = @( @("True") , @("False") )[!$false]
write-host "d:" $d

However, the use of @(), the array-subexpression operator seems both redundant and ineffective, depending on your intent; the above is equivalent to:

$d = ( "True", "False" )[!$false]
write-host "d:" $d

Note that @(...) is never required for array literals; use of ,, the array constructor operator, is generally sufficient. See the middle section of this answer for more information.

If you want $d to be an array, you need to apply @(...) to the entire expression:

# $d is now a 1-element array containing 'False'
$d = @(( "True", "False" )[!$false])
write-host "d:" $d

Alternatively, type-constrain $d to be an array:

# $d is now a 1-element array containing 'False'
[array] $d = ( "True", "False" )[!$false]
write-host "d:" $d
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you, it worked. The concret application was to eliminate element number x from array $a by joining the preceeding and succeeding parts: $LastElement = $a.GetUpperBound(0); if ($LastElement -ge 0) { $a = @(@(@(),@($a[0..($x-1)]))[$x -ne 0]; @(@(), @($a[($x+1)..$LastElement]))[$x -ne $LastElement]) }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.