2

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?

miguello
  • 544
  • 5
  • 15

4 Answers4

5

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 | ...
mklement0
  • 382,024
  • 64
  • 607
  • 775
2

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.

miguello
  • 544
  • 5
  • 15
  • 1
    Note that there's no good reason to use `[psobject]` in user code; `[object[]]` will do or - more simply - `[array]`. In fact, wrapping objects in `[psobject]` instances can have subtle, unwanted side effects - see [GitHub issue #5579](https://github.com/PowerShell/PowerShell/issues/5579). – mklement0 Dec 23 '20 at 21:56
1

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: @()

gjh71
  • 17
  • 4
0

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.

Adam
  • 3,891
  • 3
  • 19
  • 42
Esperento57
  • 16,521
  • 3
  • 39
  • 45