3

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 4

9

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 | ...
Sign up to request clarification or add additional context in comments.

Comments

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.

1 Comment

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

Comments

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.