Page 1 of 1

ArrayList of ArrayLists

Posted: Thu Aug 08, 2019 7:52 am
by azeiler
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.

Code: Select all

function Get-Data()
{
[CmdletBinding()]
param (
[Parameter(Mandatory = $True, ValueFromPipeline = $True)]
[System.Collections.ArrayList]$ModuleBlocks
)

BEGIN
{
}
PROCESS
{
$ModuleBlocks | %{

$test = $_

}

}
END { }

}

$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

Re: ArrayList of ArrayLists

Posted: Thu Aug 08, 2019 9:32 am
by jvierra
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 

Re: ArrayList of ArrayLists

Posted: Thu Aug 08, 2019 9:35 am
by jvierra
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