Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Powershell : Why I cannot use ForEach-Object to modify elements?

I've got an array definition:

> $a={"abc","xyz","hello"}

Then, using foreach to modify it, but seems original elements are not changed:

> foreach($i in $a){$i="kkk"+$i}
> $a
> "abc","xyz","hello"

Why foreach loop doesn't modify elements? Then I tried to use ForEach-Object, this time, it doesn't even run:

> $a|%{$_=$_+"kkk"}
Method invocation failed because [System.Management.Automation.ScriptBlock] does not contain a method named 'op_Addition'.
At line:1 char:6
+ $a|%{$_=$_+"kkk"}
+      ~~~~~~~~~~~
+ CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound

Does this has any syntax error? Or my understanding is incorrect?

like image 338
vik santata Avatar asked Jul 31 '26 00:07

vik santata


1 Answers

You don't have an array in $a, you have a [ScriptBlock]. Curly braces {} denote a script block in PowerShell.

The array operator is @().

This is the cause of the error in the second example.

$a=@("abc","xyz","hello")

foreach($i in $a) {
    $i = "zzz" + $i
}

$a | % { $_ += "zzz" }

However, this still will not work, because $i and $_ are copies, not references back to the original array location.

Instead, you can iterate over the array using a regular for loop:

for( $i = 0 ; $i -lt $a.Count ; $i++ ) {
    $a[$i] += "zzz"
}

In this example you can see that in the loop body, you are referring directly to the array in $a and modifying its actual value.

Also note that ForEach-Object (%) returns a value (or all of the values returned from the block), so you could also do this:

$a = $a | % { "qqq" + $_ }

However this is forming a brand new array and assigning it to $a, not really modifying the original.

like image 135
briantist Avatar answered Aug 01 '26 15:08

briantist