How to test for $null array in PowerShell

前端 未结 6 978
感情败类
感情败类 2020-12-08 00:24

I\'m using an array variable in PowerShell 2.0. If it does not have a value, it will be $null, which I can test for successfully:

PS C:\\> [array]$foo =          


        
相关标签:
6条回答
  • 2020-12-08 00:49
    if($foo -eq $null) { "yes" } else { "no" }
    
    help about_comparison_operators 
    

    displays help and includes this text:

    All comparison operators except the containment operators (-contains, -notcontains) and type operators (-is, -isnot) return a Boolean value when the input to the operator (the value on the left side of the operator) is a single value (a scalar). When the input is a collection of values, the containment operators and the type operators return any matching values. If there are no matches in a collection, these operators do not return anything. The containment operators and type operators always return a Boolean value.

    0 讨论(0)
  • 2020-12-08 00:56

    You can reorder the operands:

    $null -eq $foo
    

    Note that -eq in PowerShell is not an equivalence relation.

    0 讨论(0)
  • 2020-12-08 00:57

    The other answers address the main thrust of the question, but just to comment on this part...

    PS C:\> [array]$foo = @("bar")
    PS C:\> $foo -eq $null
    PS C:\>
    

    How can "-eq $null" give no results? It's either $null or it's not.

    It's confusing at first, but that is giving you the result of $foo -eq $null, it's just that the result has no displayable representation.

    Since $foo holds an array, $foo -eq $null means "return an array containing the elements of $foo that are equal to $null". Are there any elements of $foo that are equal to $null? No, so $foo -eq $null should return an empty array. That's exactly what it does, the problem is that when an empty array is displayed at the console you see...nothing...

    PS> @()
    PS> 
    

    The array is still there, even if you can't see its elements...

    PS> @().GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS> @().Length
    0
    

    We can use similar commands to confirm that $foo -eq $null is returning an array that we're not able to "see"...

    PS> $foo -eq $null
    PS> ($foo -eq $null).GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS> ($foo -eq $null).Length
    0
    PS> ($foo -eq $null).GetValue(0)
    Exception calling "GetValue" with "1" argument(s): "Index was outside the bounds of the array."
    At line:1 char:1
    + ($foo -eq $null).GetValue(0)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : IndexOutOfRangeException
    

    Note that I am calling the Array.GetValue method instead of using the indexer (i.e. ($foo -eq $null)[0]) because the latter returns $null for invalid indices and there's no way to distinguish them from a valid index that happens to contain $null.

    We see similar behavior if we test for $null in/against an array that contains $null elements...

    PS> $bar = @($null)
    PS> $bar -eq $null
    PS> ($bar -eq $null).GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS> ($bar -eq $null).Length
    1
    PS> ($bar -eq $null).GetValue(0)
    PS> $null -eq ($bar -eq $null).GetValue(0)
    True
    PS> ($bar -eq $null).GetValue(0) -eq $null
    True
    PS> ($bar -eq $null).GetValue(1)
    Exception calling "GetValue" with "1" argument(s): "Index was outside the bounds of the array."
    At line:1 char:1
    + ($bar -eq $null).GetValue(1)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
        + FullyQualifiedErrorId : IndexOutOfRangeException
    

    In this case, $bar -eq $null returns an array containing one element, $null, which has no visual representation at the console...

    PS> @($null)
    PS> @($null).GetType()
    
    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     Object[]                                 System.Array
    
    
    PS> @($null).Length
    1
    
    0 讨论(0)
  • 2020-12-08 00:58

    How do you want things to behave?

    If you want arrays with no elements to be treated the same as unassigned arrays, use:

    [array]$foo = @() #example where we'd want TRUE to be returned
    @($foo).Count -eq 0
    

    If you want a blank array to be seen as having a value (albeit an empty one), use:

    [array]$foo = @() #example where we'd want FALSE to be returned
    $foo.PSObject -eq $null
    

    If you want an array which is populated with only null values to be treated as null:

    [array]$foo = $null,$null
    @($foo | ?{$_.PSObject}).Count -eq 0 
    

    NB: In the above I use $_.PSObject over $_ to avoid [bool]$false, [int]0, [string]'', etc from being filtered out; since here we're focussed solely on nulls.

    0 讨论(0)
  • 2020-12-08 01:00

    If your solution requires returning 0 instead of true/false, I've found this to be useful:

    PS C:\> [array]$foo = $null
    PS C:\> ($foo | Measure-Object).Count
    0
    

    This operation is different from the count property of the array, because Measure-Object is counting objects. Since there are none, it will return 0.

    0 讨论(0)
  • 2020-12-08 01:01

    Its an array, so you're looking for Count to test for contents.

    I'd recommend

    $foo.count -gt 0
    

    The "why" of this is related to how PSH handles comparison of collection objects

    0 讨论(0)
提交回复
热议问题