Home > Back-end >  Check if a list of values has the same values as in other list
Check if a list of values has the same values as in other list

Time:01-13

I parse a text file with values and collect the individual values in a list. If there are sufficient bytes the list is sent to the output in Intel-HEX format. I want to suppress the lines where all values are 0xFF.

For that purpose I define a list $emptyline and fill it with the desired pattern. Now I want to compare the two list.

$empty = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFF)

$values.Equals($empty)

Surprisingly the last expression results in False. How do I check for the line with all values 0xFF?

CodePudding user response:

I want to suppress the lines where all values are 0xFF.

If you want to check if all items are 0xFF then you can just iterate over them and look for any values that are not 0xFF.

# make some test data - a million 0xff
$x = @(0xff) * 1000000;

$valid = $true;
foreach( $i in $x )
{
    if( $i -ne 0xFF )
    {
        $valid = $false;
        break;
    }
}

write-host $valid;
# True

This takes about 400ms on my machine, but fails as soon as it finds a non-0xFF so invalid data is faster:

# make some test data - a 0x00 followed by a million 0xff
$x = @(0x00)   (@(0xff) * 1000000);

takes about 3.5ms.

CodePudding user response:

How about this way:

PSObject.CompareTo(Object) Method

https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.psobject.compareto?view=powershellsdk-7.3.0

$empty  = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFF)

("$empty").CompareTo("$values")
# Results
<#
0
#>

$empty  = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFFF)

("$empty").CompareTo("$values")
# Results
<#
-1
#>

CodePudding user response:

tl;dr

$empty = (0xFF, 0xFF, 0xFF, 0xFF)
$values = (0xFF, 0xFF, 0xFF, 0xFF)

# -> $true
([Collections.IStructuralEquatable] $values).Equals(
  $empty,
  [Collections.Generic.EqualityComparer[int]]::Default
)

$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.

  • Related