Gordon
Gordon

Reputation: 6863

Group-Object, get counts

Given a list with some duplicate items, I can use Group-Object -AsHashtable and I get a hash table that seems to have keys with the item names, and the value is something I don't recognize.

So, given

$array = [System.Collections.Generic.List[String]]@('A', 'B', 'C', 'B', "c", 'C')
$grouped = $array | Group-Object -AsHashTable

$grouped will be

Name                           Value                                                                                                                                                                                                                                              
----                           -----                                                                                                                                                                                                                                              
A                              {A}                                                                                                                                                                                                                                                
B                              {B, B}                                                                                                                                                                                                                                             
C                              {C, c, C}  

At which point I would have thought that $grouped['B'].Count or $grouped.'B'.Count would produce the correct count of 2. But I am getting 0. What am I missing?

Upvotes: 3

Views: 1664

Answers (2)

NeoTheNerd
NeoTheNerd

Reputation: 656

Please Note This Was Done On PowerShell Version 7.2 & Not Version 5 Which Was The Question. 05.12.2021

try the below (it worked for me, see pic)

$array = [System.Collections.Generic.List[String]]@('A', 'B', 'C', 'B', "c", 'C')
$grouped = $array | Group-Object -AsHashTable
$grouped.B 
$grouped.B.Count

Write-Host $grouped.B.Count

$b = $grouped.B.Count
Write-Host "The Number of Values in Column B Is - $b"

enter image description here

Upvotes: -1

mklement0
mklement0

Reputation: 438083

You're seeing a bug in Windows PowerShell that has since been fixed in PowerShell (Core) 7+ - see GitHub issue #6933 for details.

Workaround: In Windows PowerShell, always combine -AsHashTable with -AsString, even if the input objects or grouping property values already are strings. Tip of the hat to Abraham Zinala.

# Note: .B.Count is equivalent to ['B'].Count
PS> ('A', 'B', 'C', 'B', "c", 'C' | Group-Object -AsHashTable -AsString).B.Count

2 # OK, thanks to -AsString (not necessary in PowerShell 7+)

This bypasses the bug, which otherwise manifests as follows: the strings that are meant to become the hashtable keys are unexpectedly wrapped in invisible [psobject] wrappers, which in turn prevents string-based key lookup.
(('A', 'B', 'C', 'B', "c", 'C' | Group-Object -AsHashTable).B yields $null in Windows PowerShell.)

Note: The implication is that you cannot use -AsHashtable in Windows PowerShell if you want the keys to be of a data type other than string (e.g. [int]), because for such data types the invisible [psobject] wrapping cannot be bypassed.

Upvotes: 2

Related Questions