Why Does Array Indexing Behave Differently Inside a PowerShell String?

0
0
Asked By MellowCedar47 On

I'm trying to format all arguments passed to a PowerShell function:

function lf {
if ($args) {
(0..($args.Count - 1) | ForEach-Object { "$args[$_]" }) -join ','
(0..($args.Count - 1) | ForEach-Object { "$($args[$_])" }) -join ','
} else {
...
}
}

lf pdf png txt

The output is:

[0],[1],[2]
,,

I expected both expressions to produce `pdf,png,txt`. Direct indexing such as `$args[0]` works, so why does indexing with the pipeline variable fail in the first expression?

2 Answers

Answered By QuietMaple22 On

A cleaner approach is to declare the function’s arguments with a `param` block instead of relying on the automatic `$args` variable. For example:

function lf {
param(
[Parameter(ValueFromRemainingArguments)]
[string[]] $FileTypes
)

if ($FileTypes) {
$FileTypes -join ','
} else {
...
}
}

This makes the expected inputs explicit and eliminates the ambiguity around `$args`.

BriskLantern6 -

Agreed. Using a named parameter is easier to understand and gives the function a clearer interface.

Answered By PixelHarbor8 On

In an expandable PowerShell string, `$args[$_]` is parsed as the variable `$args` followed by literal text like `[0]`, rather than as an evaluated array lookup. That’s why the first expression produces `[0],[1],[2]`. Wrapping the expression in a subexpression forces PowerShell to evaluate the index operation: `$($args[$_])`. You can also avoid indexing entirely and pipe the arguments directly:

($args | ForEach-Object { $_ }) -join ','

MellowCedar47 -

That explains the different output. The subexpression form works; I was mainly confused because `$args[0]` works when the index is written as a literal.

Related Questions

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.