tl;dr
$empty = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFF)
# -> $true
([Collections.IStructuralEquatable] $values).Equals(
$empty,
[Collections.Generic.EqualityComparer[int]]::Default
)
See the next section for an explanation.
- Pragmatic shortcut via string comparison, which assumes that the array elements stringify meaningfully and unambiguously (which is the case here):
# -> $true, i.e. the values are equal
"$values" -eq "$empty"
This relies on PowerShell's built-in array (collection) stringification, which joins the (stringified) elements with spaces (e.g., "$(1, 2)"
-> "1 2"
)
- Looking for non-
0xFF
values in a single array:
# -> $true, i.e. all values are 0xFF
($values -ne 0xFF).Count -eq 0
This relies on PowerShell's comparison operators such as -eq
and its negated form, -ne
, acting as filters if their LHS is an array (collection), i.e. they return a (new) sub-array of matching values.
As for what you tried:
$values.Equals($empty)
Surprisingly the last expression results in False
Your .Equals
call calls the bool Equals(System.Object obj)
method overload, which tests for reference equality, meaning that $true
is only returned if the operands refer to the exact same array instance; e.g.:
# !! $false, because the two arrays - despite having the same(-valued) elements -
# !! are *different array instances*.
@(1, 2).Equals(@(1, 2))
However, there is an .Equals()
overload that does what you want, namely that provided by the System.Collections.IStructuralEquatable
interface, which has two parameters:
bool IStructuralEquatable.Equals(System.Object other, System.Collections.IEqualityComparer comparer)
Using that overload performs the element-by-element comparison you want, as shown above, with the help of a default System.Collections.Generic.EqualityComparer<T>
instance that implements the System.Collections.IEqualityComparer
interface.
An alternative is to use the Compare-Object
cmdlet, which is quite flexible and would also allow you identify specific differences between two arrays, if needed:
$empty = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFF)
# -> $true
-not (Compare-Object -SyncWindow 0 $empty $values | Select-Object -First 1)
Compare-Object
returns only elements that differ between the input arrays (collections) by default, so the presence of any output implies that at least one difference was found.
-not
implicitly treats the output as a [bool]
, which, based on PowerShell's implicit to-Boolean coercion rules (see the bottom section of this answer), means that no output yields $false
, whereas a [pscustomobject]
as output by Compare-Object
yields $true
.
-SyncWindow 0
and | Select-Object -First 1
are optimizations (which may not be necessary for small arrays):
-SyncWindow 0
ensures that only directly corresponding elements are compared; by default, the order of the elements doesn't matter. This allows for much faster comparison.
Select-Object -First 1
stops processing once Compare-Object
has found the first difference, if any.