Naga
Naga

Reputation: 367

How to get Count of Values from a Hashtable per key in powershell

Currently I am able to get the list of values from a hashtable with the below cmdlet, but I would like get a count of values per key. Please lend me some advice, if this can be achieved using GetEnumerator method

$keys.GetEnumerator() | % {
    [PSCustomObject]@{
        key = $_.Value
    }
}

My Hashtable $keys:

Name                           Value                                                                                                 
----                           -----  
9                              {G637A146}                                                                 
-3                             {F637A146, G637A146}                            
3                              {F637A146, E637A146}                            
-2                             {F637A146} 

Expected Output Using GetEnumerator:

Key     Value                                                                                                 
----    ----- 
9       1
-3      2
3       2
-2      1

New Edit: 2. How to get the unique count of values as well? My Hashtable $keys:

Name                           Value                                                                                                 
----                           -----  
9                              {G637A146, F637A146, J637A146}                                                                 
-3                             {F637A146, F637A146, G637A146, F637A146}

Expected Output Using GetEnumerator:

Key     Value                                                                                                 
----    ----- 
9       3
-3      2

Upvotes: 1

Views: 2457

Answers (2)

Theo
Theo

Reputation: 61068

Supposing your hashtable looks like this:

$keys = [ordered]@{
    9  = 'G637A146'
    -3 = 'F637A146', 'G637A146'
    3  = 'F637A146', 'E637A146'
    -2 = 'F637A146'
}

Then this should get you what you want:

$keys.GetEnumerator() | ForEach-Object {
    [PSCustomObject]@{
        Key   = $_.Key
        Value = ($_.Value).Count
    }
}

Output:

Key Value
--- -----
  9     1
 -3     2
  3     2
 -2     1


Update

You could create a second hashtable where you keep track of the count values and only output if that vaue has not been seen before:

$seenThisBefore = @{}
$keys.GetEnumerator() | ForEach-Object {
    $count = ($_.Value).Count
    if (!$seenThisBefore.ContainsKey($count)) {
        [PSCustomObject]@{
            Key   = $_.Key
            Value = $count
        }
        $seenThisBefore[$count] = $true  # add the count as key. The value here doesn't matter
    }
} 

Upvotes: 1

ojintoad
ojintoad

Reputation: 453

I think you can cast the value to an array and then get the Count property.

So:

$keys.GetEnumerator() | % {
    [PSCustomObject]@{
        key = @($_.Value).Count
    }
}

if I'm understanding your code correctly.

This is called the array sub-expression operator according to about_Arrays.


Since the comment response of the prior suggestion indicates that the format of the output for value isn't of some object but rather a string, then the value would need to be parsed.

Here's an example of how that might be done:

@('{a,b}' -replace '{', '' -replace '}', '' -split ',').Count

which produces the output of 2.

That just uses operators as documented on about_Operators

Upvotes: 0

Related Questions