How do I format array of hastables into a Table?

This topic contains 10 replies, has 3 voices, and was last updated by Profile photo of Martin Nielsen Martin Nielsen 1 year, 9 months ago.

  • Author
    Posts
  • #23362
    Profile photo of GS
    GS
    Participant

    Hello,

    How do I format into a table such a structure where columns in table will be Hashtable's indexes

    Code

    $array = @();
    $hashtable = @{Col1="1"; Col2="2"};
    $array += $hashtable;
    $array += $hashtable;
    $array | ft
    

    Output

    Name                           Value                                                                                                                
    ----                           -----                                                                                                                
    Col2                           2                                                                                                                    
    Col1                           1                                                                                                                    
    Col2                           2                                                                                                                    
    Col1                           1  
    

    Desired Output

    Col1 Col2
    1 2
    1 2
    
  • #23367
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You need to turn your hashtables into objects with Col1 and Col2 as properties. As it turns out, that's incredibly easy:

    # PowerShell 3.0 and later:
    
    $array | ForEach-Object { [pscustomobject] $_ } | Format-Table
    
    # PowerShell 2.0-compatible:
    
    $array | ForEach-Object { New-Object -TypeName psobject -Property $_ } | Format-Table
    
  • #23368
    Profile photo of GS
    GS
    Participant

    This did not work. I'm V4

    $array = @();
    $hashtable = @{Col1="1"; Col2="2"};
    $array += $hashtable;
    $array += $hashtable;
    $array | ForEach-Object { [pscustomobject] $_ } | Format-Table
    

    output

    Name                           Value                                                                                                                
    —-                           —–                                                                                                                
    Col2                           2                                                                                                                    
    Col1                           1                                                                                                                    
    Col2                           2                                                                                                                    
    Col1                           1                                                                                                                    
    
    
    
  • #23370
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Don't know what to tell you. I ran the code before I posted, and it works fine for me.

  • #23371
    Profile photo of GS
    GS
    Participant

    How is this possible? This works for you?

  • #23373
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    I'm not seeing an image in your last post, but here's what works for me. I'm running the latest preview of PowerShell 5.0, but as far as I know, nothing's changed with the way this works since v3. (I don't have any older systems online at the moment to test, though).

  • #23375
    Profile photo of GS
    GS
    Participant
  • #23377
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    Well, do it the other way, then. 🙂

  • #23378
    Profile photo of GS
    GS
    Participant

    Yes, v2 way works but I do have v4 though

    PS C:\WINDOWS\system32> $PSVersionTable

    Name Value
    —- —–
    PSVersion 4.0
    WSManStackVersion 3.0
    SerializationVersion 1.1.0.1
    CLRVersion 4.0.30319.34014
    BuildVersion 6.3.9600.17090
    PSCompatibleVersions {1.0, 2.0, 3.0, 4.0}
    PSRemotingProtocolVersion 2.2

  • #23389
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    I'm seeing the same thing, so it's not just your PowerShell misbehaving.

    PS C:\Users\Martin> $array = @();
    $hashtable = @{Col1="1"; Col2="2"};
    $array += $hashtable;
    $array += $hashtable;
    $array | ForEach-Object { [pscustomobject] $_ } | Format-Table
    
    Name                           Value                                                                                                                                  
    ----                           -----                                                                                                                                  
    Col2                           2                                                                                                                                      
    Col1                           1                                                                                                                                      
    Col2                           2                                                                                                                                      
    Col1                           1                                                                                                                                      
    
    
    
    PS C:\Users\Martin> $array = @();
    $hashtable = @{Col1="1"; Col2="2"};
    $array += $hashtable;
    $array += $hashtable;
    $array | ForEach-Object { New-Object psobject -Property $_ } | Format-Table
    
    
    
    Col2                                                                                Col1                                                                              
    ----                                                                                ----                                                                              
    2                                                                                   1                                                                                 
    2                                                                                   1                                                                                 
    
    
    
    PS C:\Users\Martin> $Host
    
    
    Name             : Windows PowerShell ISE Host
    Version          : 4.0
    InstanceId       : 95a1a0f8-a342-44e6-a47e-5a2cdc5ae206
    UI               : System.Management.Automation.Internal.Host.InternalHostUserInterface
    CurrentCulture   : en-US
    CurrentUICulture : en-US
    PrivateData      : Microsoft.PowerShell.Host.ISE.ISEOptions
    IsRunspacePushed : False
    Runspace         : System.Management.Automation.Runspaces.LocalRunspace
    

    But with that said, I never liked the typecasting approach, and New-Object is faster anyway.

    Fiddling around with it, I see that I can typecast the $hashtable variable, but I can't typecast the pipeline object taken from an array of hashtables. Interesting.

    PS C:\Users\Martin> [pscustomobject]$array[0]
    
    Col2                                                                                Col1                                                                              
    ----                                                                                ----                                                                              
    2                                                                                   1                                                                                 
    
    
    
    PS C:\Users\Martin> $array | foreach { [pscustomobject]$_ }
    
    Name                           Value                                                                                                                                  
    ----                           -----                                                                                                                                  
    Col2                           2                                                                                                                                      
    Col1                           1                                                                                                                                      
    Col2                           2                                                                                                                                      
    Col1                           1                                                                                                                                      
    
    
    
    PS C:\Users\Martin> $array | foreach { $_.GetType() }
    
    IsPublic IsSerial Name                                     BaseType                                                                                                   
    -------- -------- ----                                     --------                                                                                                   
    True     True     Hashtable                                System.Object                                                                                              
    True     True     Hashtable                                System.Object                                                                                              
    
    
    
    PS C:\Users\Martin> $array[0].GetType()
    
    IsPublic IsSerial Name                                     BaseType                                                                                                   
    -------- -------- ----                                     --------                                                                                                   
    True     True     Hashtable                                System.Object          
    

    Actually typecasting is faster. Damn.

  • #23391
    Profile photo of Martin Nielsen
    Martin Nielsen
    Participant

    It appears to be a bug when piping into the ForEach-Object cmdlet. I can't seem to reproduce it using any other looping method.

    PS C:\Users\Martin> foreach($item in $array) { [pscustomobject]$item }
    
    Col2                                                                                Col1                                                                              
    ----                                                                                ----                                                                              
    2                                                                                   1                                                                                 
    2                                                                                   1                                                                                 
    
    PS C:\Users\Martin> $array.ForEach({ [pscustomobject]$_ })
    
    Col2                                                                                Col1                                                                              
    ----                                                                                ----                                                                              
    2                                                                                   1                                                                                 
    2                                                                                   1                                                                                 
    

    Even passing a single item into ForEach-Object fails

    PS C:\Users\Martin> $array[0] | ForEach-Object { [pscustomobject]$_ }
    
    Name                           Value                                                                                                                                  
    ----                           -----                                                                                                                                  
    Col2                           2                                                                                                                                      
    Col1                           1                                                                                                                                      
    

You must be logged in to reply to this topic.