Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 536 Vote(s) - 3.53 Average
  • 1
  • 2
  • 3
  • 4
  • 5
How to handle $null in the pipeline

#1
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?

Reply

#2
A quick note to Keith's answer to complete it

Personally, I would return *nothing*. It makes sense:

PS> function Empty { if ('a' -eq 'b') { 'equal' } }
PS> Empty | % { write-host result is $_ }

But now you are in problems if you assign result from `Empty` to a variable:

PS> $v = Empty
PS> $v | % { write-host result is $_ }

There is a little trick to make it work. Just wrap the result from `Empty` as a array like this:

PS> $v = @(Empty)
PS> $v | % { write-host result is $_ }
PS> $v.GetType()
IsPublic IsSerial Name BaseType
-------- -------- ---- --------
True True Object[] System.Array
PS> $v.Length
0
Reply

#3
Another possibility:

$objects | Foreach-Object -Begin{If($_ -eq $null){continue}} -Process {do your stuff here}

More info in [about_Continue][1]


[1]:

[To see links please register here]

Reply

#4
If you can modify your function, have it return an empty collection/array instead of $null:

PS> function Empty { $null }
PS> Empty | %{'hi'}
hi

PS> function Empty { @() }
PS> Empty | %{'hi'}

Otherwise, go with what Oisin suggests although I would suggest a slight tweak:

filter Skip-Null { $_|?{ $_ -ne $null } }

Otherwise this will also filter `0` and `$false`.

**Update 4-30-2012:** This issue is fixed in PowerShell v3. V3 will not iterate over a scalar $null value.
Reply

#5
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

Reply



Forum Jump:


Users browsing this thread:
2 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through