Getting the count of a hashtable that only has one key/value in it
Asked Answered
P

2

3

I have a foreach loop that currently puts three entries in my hashtable:

$result = foreach($key in $serverSpace.Keys){
    if($serverSpace[$key] -lt 80){
        [pscustomobject]@{
            Server = $key
            Space = $serverSpace[$key]}}}

When I use

$result.count

I get 3 as expected. I changed the foreach loop to exlude the entries less than or equal to one using

$result = foreach($key in $serverSpace.Keys){
    if($serverSpace[$key] -lt 80 -and $serverSpace[$key] -gt 1){
        [pscustomobject]@{
            Server = $key
            Space = $serverSpace[$key]}}}

$result.count should have 1 as its output but it doesn't recognize .count as a suggested command and $result.count doesn't output anything anymore. I'm assuming when theres only one entry in the hash table it won't allow a count? Not sure whats going on but my conditions for my script are dependent on the count of $result. Any help would be appreciated.

Planter answered 12/7, 2021 at 15:24 Comment(5)
Force it to be an array: @($result).countSublunar
[1] that PSCO is NOT a hashtable. [grin] [2] if you want a single object to have a .Count property, you need to make that object into a collection. the easiest way is to prefix the $Var name with [array].Carnelian
Oh wow I'm dumb. That makes sense. Thank you to both of youPlanter
Does this answer your question? Powershell being too cleverMichelmichelangelo
Terminology note: What your foreach loop is returning is one or more custom objects ([pscustomobject] instances), not hashtables.Titration
P
2

$result is not a hashtable so I prefixed it with @($result).count. Thank you to @Theo and @Lee_Dailey

Planter answered 12/7, 2021 at 15:33 Comment(0)
T
1

What you're seeing is a bug in Windows PowerShell (as of the latest and final version, 5.1), which has since been corrected in PowerShell (Core) - see GitHub issue #3671 for the original bug report.

That is, since v3 all objects should have an intrinsic .Count property , not just collections, in the interest of unified treatment of scalars and collections - see this answer for more information.

The workaround for Windows PowerShell is indeed to force a value to be an array via @(...), the array-subexpression operator, which is guaranteed to have a .Count property, as shown in your answer, but it shouldn't be necessary and indeed isn't anymore in PowerShell (Core, v6+)

# !! Due to a BUG, this outputs $null in *Windows PowerShell*,
# !! but correctly outputs 1 in PowerShell (Core).
([pscustomobject] @{}).Count

# Workaround for Windows PowerShell that is effective in *both* editions,
# though potentially wasteful in PowerShell (Core):
@([pscustomobject] @{}).Count
Titration answered 13/7, 2021 at 2:19 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.