Consider this code
"Type: array"
$v = @()
" -eq `$null: $($v -eq $null)"
" -ne `$null: $($v -ne $null)"
"Type: string"
$v = ''
" -eq `$null: $($v -eq $null)"
" -ne `$null: $($v -ne $null)"
which produces the following result:
Type: array
-eq $null:
-ne $null:
Type: string
-eq $null: False
-ne $null: True
Why does -eq
and -ne
behave as expected for an empty string, but evaluate to null or empty for an empty array?
More importantly, how do you distinguish between $null
and an empty array?
String to check if a string variable is null or empty in PowerShell. The IsNullorEmpty() method indicates whether the specified string is empty or null. It returns True if the string is empty and False if it is not empty.
You can use $null to check an undefined variable. If the variable is not initialized with a value, it is undefined. This command checks if $Author is null in PowerShell. It returns the TRUE value as it is not initialized.
To create and initialize an array, assign multiple values to a variable. The values stored in the array are delimited with a comma and separated from the variable name by the assignment operator ( = ). The comma can also be used to initialize a single item array by placing the comma before the single item.
When comparison operators are used against a collection, they do not return a boolean value ($true or $false). They return all the members of the collection that meet the condition.
See:
Get-help About_Comparison_Operators
@mjolinor's answer is a simple and correct answer to question (1). That answer actually leads to two more questions.
about_Comparison_Operators states the following:
When the input is a collection of values, the comparison operators return any matching values. If there are no matches in a collection, comparison operators do not return anything.
This implies the behavior depends on Powershell's definition of "collection" in this context. Pipeline unrolling has a similar dependence on the definition of "collection". It also implies that swapping the LHS and RHS of comparison operators might make a material difference.
So in addition to the original question 2, we have two more unanswered questions:
$null
and an empty array?These three remaining questions can all be answered empirically using the script at the end of this answer.
CollectionType x_eq_Null coll_LHS_result Null_eq_x coll_RHS_result
-------------- --------- --------------- --------- ---------------
string False Boolean False Boolean
ArrayList {} Object[] False Boolean
Hashtable False Boolean False Boolean
Queue {} Object[] False Boolean
SortedList False Boolean False Boolean
Stack {} Object[] False Boolean
Dictionary False Boolean False Boolean
List {} Object[] False Boolean
Null True Boolean True Boolean
boolean False Boolean False Boolean
int32 False Boolean False Boolean
char False Boolean False Boolean
We can use the table to answer the questions:
- How do you distinguish between
$null
and an empty array?
Moving the collection to the RHS of the operator (e.g. $null -eq @()
) yields a Boolean for all types tested (see column coll_RHS_result
). This means that $null -ne @()
evaluates to True as expected which allows us to reliably detect the difference between $null
and @()
.
- What types does Powershell comparison operators treat as a collection?
Each of the types whose coll_LHS_result
is Object[]
.
- Does swapping the LHS and RHS of the comparison operators make a difference?
It sure does. Putting a collection on the LHS of the operator yields an array as a result. Putting a scalar on the LHS of the operator yields a boolean as a result.
('string', ('')),
('ArrayList', (New-Object System.Collections.ArrayList)),
('Hashtable', (New-Object System.Collections.Hashtable)),
('Queue', (New-Object System.Collections.Queue)),
('SortedList', (New-Object System.Collections.SortedList)),
('Stack', (New-Object System.Collections.Stack)),
('Dictionary', (New-Object "System.Collections.Generic.Dictionary``2[System.String,int32]")),
('List', (New-Object System.Collections.Generic.List``1[int32])),
('Null', ($null)),
('boolean', ($false)),
('int32', ([int32]0)),
('char', ([char]"`0")) |
% {
New-Object PSObject -Property @{
CollectionType = $_[0]
x_eq_Null = $_[1] -eq $null
coll_LHS_result = ($_[1] -eq $null).GetType().Name
Null_eq_x = $null -eq $_[1]
coll_RHS_result = ($null -eq $_[1]).GetType().Name
}
} |
select CollectionType,x_eq_Null,coll_LHS_result,Null_eq_x,coll_RHS_result |
ft -AutoSize
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