Share via


how to use .Foreach() method for a list in powershell?

Question

Tuesday, December 18, 2018 5:59 AM

I wanna use list.Foreach() method in powershell, sample code as below:

$s=New-Object System.Collections.Generic.List[string]
$s.Add("hello_1")
$s.Add("hello_2")
$s.Add("hello_3")
if I use $s.foreach({$_}), then nothing output. can you tell me why?I also find some other usage which can work well, like $s.GetEnumerator().foreach({$_}) or $s.ForEach({write-host $args[0].ToString()}).But now I want to know why $s.foreach({$_}) does not work? any reasons?

All replies (4)

Tuesday, December 18, 2018 8:50 AM ✅Answered

Look at the definition of the argument for "ForEach":

PS D:\scripts> $s.ForEach

OverloadDefinitions

void ForEach(System.Action[string] action)

Notice it wants an "Action" object.

PS D:\scripts> [System.Action[string]]

IsPublic IsSerial Name                                     BaseType
                                       
True     True     Action`1                                 System.MulticastDelegate

The Action object is a multicast delegate. 

The construct is designed to support the Linq syntax.  See the following.

https://stackoverflow.com/questions/2834094/what-is-actionstring

In PowerShell:

PS D:\scripts> $s = New-Object System.Collections.Generic.List[string]
PS D:\scripts> $s.Add("hello_1")
PS D:\scripts> $s.Add("hello_2")
PS D:\scripts> $s.Add("hello_3")
PS D:\scripts> $s.ForEach({
>>         param ($x)
>>         Write-Host $x
>> })
hello_1
hello_2
hello_3
PS D:\scripts>

\(ツ)_/


Tuesday, December 18, 2018 7:05 AM

How do I properly use ForEach() statement of List?

Trying to use ForEach() method and confused what I'm doing wrong

You might ask Microsoft why it is like it is.  ;-)   ... if you think it's a bug you should report it to Microsoft.

Live long and prosper!

(79,108,97,102|%{[char]$_})-join''


Tuesday, December 18, 2018 8:56 AM

PS D:\scripts> $ints = New-Object System.Collections.Generic.List[int]
PS D:\scripts> $ints.Add(1)
PS D:\scripts> $ints.Add(2)
PS D:\scripts> $ints.Add(3)
PS D:\scripts> $ints.ForEach({
>>     param ($i)
>>     Write-Host ($i * 10)
>> })
10
20
30
PS D:\scripts>
PS D:\scripts> $ints.FindAll({Param($i) $i -gt 1})
2
3
PS D:\scripts>

\(ツ)_/


Tuesday, December 18, 2018 9:06 AM

All of the Linq extensions to the PS/Net objects take a delegate.  The delegate in PS is created from a scriptblock that is passed to the extension method.

For simple collections we can use the pipeline variable:

PS D:\scripts> $a = 1,2,3,4,5,6
PS D:\scripts> $a.ForEach({$_})
1
2
3
4
5
6
PS D:\scripts> $a.Where({$_ -gt 3})
4
5
6

We can also call complex code in a function

PS D:\scripts> function foo{Write-Host $_}
PS D:\scripts> $a.ForEach($function:foo)
1
2
3
4
5
6

\(ツ)_/