ArrayList of ArrayLists

Ask your Windows PowerShell-related questions, including questions on cmdlet development!
Forum rules
Do not post any licensing information in this forum.

Any code longer than three lines should be added as code using the 'Select Code' dropdown menu or attached as a file.
Locked
azeiler
Posts: 12
Joined: Fri Nov 09, 2018 1:20 pm

ArrayList of ArrayLists

Post by azeiler » Thu Aug 08, 2019 7:52 am

I've got an ArrayList of ArrayLists of Strings that I need to process with an advanced function. I am modeling that function off of what I learned in "Learn Powershell Toolmaking in a Month of Lunches."

In order to make the functions flexible, they tell you in that book to set it up so that a parameter can be piped in, but also taken as an array. So basically, you make the advanced function to accept ValuesFromPipeline for a particular parameter, but then you also make that parameter type an array and add a ForEach-Object in your Process.

What I am running into is that if I configure my function this way, it no longer works to pipe the values in. Because then it treats them one at a time, and the ForEach-Object breaks that ArrayList into its subsequent strings for processing. Is there an easy way to prevent this?

See code example below. When I pass $OutsideArray to Get-Data as a normal parameter (Get-Data $OutsideArray), it works. When I remove the ForEach-Object in the function, it works. But when I pipe $OutsideArray in as is, it no longer works.
  1. function Get-Data()
  2.  
  3. {
  4.  
  5.     [CmdletBinding()]
  6.  
  7.     param (
  8.  
  9.         [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
  10.  
  11.         [System.Collections.ArrayList]$ModuleBlocks
  12.  
  13.     )
  14.  
  15.    
  16.  
  17.     BEGIN
  18.  
  19.     {
  20.  
  21.     }
  22.  
  23.     PROCESS
  24.  
  25.     {
  26.  
  27.         $ModuleBlocks | %{
  28.  
  29.            
  30.  
  31.             $test = $_
  32.  
  33.  
  34.  
  35.         }
  36.  
  37.        
  38.  
  39.     }
  40.  
  41.     END { }
  42.  
  43.    
  44.  
  45. }
  46.  
  47.  
  48.  
  49. $OutsideArray = New-Object System.Collections.ArrayList
  50.  
  51.  
  52.  
  53. For ($i = 0; $i -lt 10; $i++)
  54.  
  55. {
  56.  
  57.    
  58.  
  59.     $InsideArray = New-Object System.Collections.ArrayList
  60.  
  61.    
  62.  
  63.     For ($j = 0; $j -le 10; $j++)
  64.  
  65.     {
  66.  
  67.         $InsideArray.Add("$i This is a test $j") | Out-Null
  68.  
  69.     }
  70.  
  71.    
  72.  
  73.     $OutsideArray.Add($InsideArray) | Out-Null
  74.  
  75.    
  76.  
  77. }
  78.  
  79.  
  80.  
  81. $OutsideArray | Get-Data

jvierra
Posts: 13992
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: ArrayList of ArrayLists

Post by jvierra » Thu Aug 08, 2019 9:32 am

The enumerator will enumerate the array in a pipeline. That is expected. How you design this depends on the intended use. I suggest gaining more experience with PowerShell and Advanced Functions before trying to do this. When yu have a real-world example then you will be able to ask a question that can be answered.

Run the following to see what is happening:

Code: Select all

function Get-Data() {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $True, ValueFromPipeline = $True)]
        [System.Collections.ArrayList]$ModuleBlocks
    )
    begin {
        Write-Host 'Begin called'
    }
    process {
        Write-Host 'Process called' -Fore green
        $ModuleBlocks | 
            ForEach-Object{
                Write-Host "`t`tForeach loop" -Fore Yellow
                $test = $_
            }
    }
    end {
        Write-Host 'Begin called'
    }
}

$OutsideArray = New-Object System.Collections.ArrayList
For ($i = 0; $i -lt 10; $i++) {  
    $InsideArray = New-Object System.Collections.ArrayList
    For ($j = 0; $j -le 10; $j++) {
        $InsideArray.Add("$i This is a test $j") | Out-Null
    }
    $OutsideArray.Add($InsideArray) | Out-Null
}

$OutsideArray | Get-Data 

jvierra
Posts: 13992
Joined: Tue May 22, 2007 9:57 am
Contact:

Re: ArrayList of ArrayLists

Post by jvierra » Thu Aug 08, 2019 9:35 am

This may make it more obvious.

Code: Select all


$OutsideArray = New-Object System.Collections.ArrayList
For ($i = 0; $i -lt 10; $i++) {  
    $InsideArray = New-Object System.Collections.ArrayList
    For ($j = 0; $j -le 10; $j++) {
        $InsideArray.Add("$i This is a test Outer: $i Inner: $j") | Out-Null
    }
    $OutsideArray.Add($InsideArray) | Out-Null
}

$OutsideArray | Get-Data

Locked