I often have the following situation in my PowerShell code: I have a function or property that returns a collection of objects, or $null
. If you push the results into the pipeline, you also handle an element in the pipeline if $null
is the only element.
Example:
$Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" }
If there are no features ($Project.Features returns $null), you will see a single line with "Feature name:".
I see three ways to solve this:
if ($Project.Features -ne $null) { $Project.Features | Foreach-Object { Write-Host "Feature name: $($_.Name)" } }
or
$Project.Features | Where-Object {$_ -ne $null) | Foreach-Object { Write-Host "Feature name: $($_.Name)" }
or
$Project.Features | Foreach-Object { if ($_ -ne $null) { Write-Host "Feature name: $($_.Name)" } } }
But actually I don't like any of these approaches, but what do you see as the best approach?
I don't think anyone likes the fact that both "foreach ($a in $null) {}" and "$null | foreach-object{}" iterate once. Unfortunately there is no other way to do it than the ways you have demonstrated. You could be pithier:
$null | ?{$_} | % { ... }
the ?{$_}
is shorthand for where-object {$_ -ne $null}
as $null
evaluated as a boolean expression will be treated as $false
I have a filter defined in my profile like this:
filter Skip-Null { $_|?{ $_ } }
Usage:
$null | skip-null | foreach { ... }
A filter is the same as a function except the default block is process {} not end {}.
UPDATE: As of PowerShell 3.0, $null
is no longer iterable as a collection. Yay!
-Oisin
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With