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

  • Question

  • 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?


    Tuesday, December 18, 2018 5:59 AM

Answers

  • 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>
    


    \_(ツ)_/

    • Proposed as answer by eeeww Wednesday, December 19, 2018 5:18 AM
    • Marked as answer by ime11 Wednesday, December 19, 2018 5:20 AM
    Tuesday, December 18, 2018 8:50 AM

All replies

  • 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 7:05 AM
  • 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>
    


    \_(ツ)_/

    • Proposed as answer by eeeww Wednesday, December 19, 2018 5:18 AM
    • Marked as answer by ime11 Wednesday, December 19, 2018 5:20 AM
    Tuesday, December 18, 2018 8:50 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>


    \_(ツ)_/


    • Edited by jrv Tuesday, December 18, 2018 8:57 AM
    Tuesday, December 18, 2018 8:56 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


    \_(ツ)_/

    Tuesday, December 18, 2018 9:06 AM