Combining Empty Arrays

This topic contains 3 replies, has 2 voices, and was last updated by  Lawrence Gulliver 2 weeks, 4 days ago.

  • Author
    Posts
  • #84788

    Lawrence Gulliver
    Participant

    I've been pulling my hair out at this one for the last few hours, seems to be down to an obscure quirk.

    (EDITED)

    Import this function:

    Function Test-Filter
    {
        [cmdletbinding()]
        Param
        (
            [Parameter(Mandatory = $true,
                ValueFromPipeline,
                Position = 0)]
            $Items
        )
        Process
        {
            $Items | Foreach-Object {
                if ($_ -eq "A")
                {
                    $output += $_
                }
            }
        }
        End
        {
            if ($output.Count -gt 0)
            { Write-Output (,$output) }
        }
    }
    

    Now run this:

    [Array]$arr1 = "A", "B", "C", "D" | Test-Filter | Sort
    [Array]$arr2 = "E", "F", "G", "H" | Test-Filter | Sort | Select -First 1
    [Array]$arr3 = 1, 2 | Test-Filter
    [Array]$arr4 = "Jolly Cooperation" | Test-Filter
    
    [Array]$combined = $arr1 + $arr2 + $arr3 + $arr4
    
    $combined.count
    

    Count is 1, as expected, $arr1 contains "A" and the rest are empty. Now run this:

    Invoke-Command {
        [Array]$arr1 = "A", "B", "C", "D" | Test-Filter | Sort
        [Array]$arr2 = "E", "F", "G", "H" | Test-Filter | Sort | Select -First 1
        [Array]$arr3 = 1, 2 | Test-Filter
        [Array]$arr4 = "Jolly Cooperation" | Test-Filter
    
        [Array]$combined = $arr1 + $arr2 + $arr3 + $arr4
    
        $combined.count
    }
    

    Count is now 4.

    This is part of a process to list patch files awaiting installation, there are four types of files but not all may be present in each patch type. Invoke-Command is required to format and log the output of the (lengthy) script but it seems to be messing with arrays somehow?

  • #84790

    Sam Boutros
    Participant

    Answer is 4 not 1 in PS 5:

    PS D:\Sandbox> [Array]$arr1 = "A"
    [Array]$arr2 = $null
    [Array]$arr3 = $null
    [Array]$arr4 = $null
    
    [Array]$combined = $arr1 + $arr2 + $arr3 + $arr4
    $combined.Count
    4
    
    PS D:\Sandbox> $PSVersionTable
    
    Name                           Value                                                                                                  
    ----                           -----                                                                                                  
    PSVersion                      5.1.15063.726                                                                                          
    PSEdition                      Desktop                                                                                                
    PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}                                                                                
    BuildVersion                   10.0.15063.726                                                                                         
    CLRVersion                     4.0.30319.42000                                                                                        
    WSManStackVersion              3.0                                                                                                    
    PSRemotingProtocolVersion      2.3                                                                                                    
    SerializationVersion           1.1.0.1    
    

    To lose the null arrays replace the line

    [Array]$combined = $arr1 + $arr2 + $arr3 + $arr4
    

    with something like

    [Array]$combined = @($arr1,$arr2,$arr3,$arr4) | % { if ($_) {$_} }
    
  • #84793

    Lawrence Gulliver
    Participant

    Edited OP with working example, I thought that one did work but as something (I think my AV) tried to shut my computer down without warning I can't be sure.

  • #84797

    Lawrence Gulliver
    Participant

    Oh, and just to further confuse things, with the above Test-Filter function:

    Invoke-Command {
        [Array]$arr1 = "A", "B", "C", "D" | Test-Filter | Sort
        [Array]$arr2 = "E", "F", "G", "H" | Test-Filter | Sort | Select -First 1
        [Array]$arr3 = 1, 2 | Test-Filter
        [Array]$arr4 = "Jolly Cooperation" | Test-Filter
    
        [Array]$combined = $arr1 + $arr2 + $arr3 + $arr4
    
        Set-Variable -Name "DebugTest" -Value $combined -Scope Global
    
        $combined.Count
    }
    
    1
    

    That one caused me some grief trying to debug it =/

    I've used a Where { $_ } which seems a bit tidier but still really weird.

You must be logged in to reply to this topic.