Powershell: How to properly count number of items in array of objects when there is only one object left in array

Viewed 3185

I have an array of objects with N properties each. I perform a subset operation using Where-Object like this, for instance:

$mySubset = $myArrayOfObjects | Where-Object {($_.Property1 -eq 'ABC') -and ($_.Property2 -eq 'DEF')}

I then need to check how many objects I have in this array. I do it like this:

$mySubset.Count

When I have more than one object in the subset array, it shows number of objects. But when I have only one object left in $mySubset - it doesn't treat it as array with one element, and $mySubset.Count returns N - number of properties in each object. This is the problem. How do I convince Powershell to treat $mySubset as an array with 1 item in it in this case?

4 Answers

The most PowerShell-idiomatic solution is to use @(), the array-subexpression operator, which ensures that a command's output is treated as an array even if only one object is returned:

$mySubset = @($myArrayOfObjects | ...)

To get the count directly: @($myArrayOfObjects | ...).Count

You can also use an [array] type constraint - in essence, a cast placed to the left of the target variable - which doesn't require modification of the RHS:

[array] $mySubset = $myArrayOfObjects | ...

Looks like this is the way:

$mySubset = [PSObject[]]($myArrayOfObjects | Where-Object {($_.Property1 -eq 'ABC') -and ($_.Property2 -eq 'DEF')})

Or, as an one liner:

([PSObject[]]($myArrayOfObjects | Where-Object {($_.Property1 -eq 'ABC') -and ($_.Property2 -eq 'DEF')})).Count

Key point is to put parenthesis in right places, so, for instance

[PSObject[]]($myArrayOfObjects | Where-Object {($_.Property1 -eq 'ABC') -and ($_.Property2 -eq 'DEF')}).Count

would still show you N instead of "1" if number of object left is one.

Sometimes this behavior is convenient, but not always....

Fortunately the workaround is simple:

$mySubset = @($myArrayOfObjects | Where-Object {($_.Property1 -eq 'ABC') -and ($_.Property2 -eq 'DEF')})

Just put the result inside the array construct: @()

Try the following:

$mySubset=@()
$mySubset += $myArrayOfObjects | Where {$_.Property1 -eq 'ABC' -and $_.Property2 -eq 'DEF'}

$mySubset.Count

I create an empty array. I filter the $myArrayOfObjects for objects where Property1 and Property2 are "ABC" and "DEF" respectively, and I save that to $mySubset. Then I give you a count of from $mySubset.

Related