0

Why does Compare-Object work as expected where -EQ fails to accurately compare arrays of strings?

I had a PowerShell script which was populating an array of strings and was using the -EQ operator to test against the expected values - this was always failing - I think the following code illustrates the issues

    # Setting up 4 Lists - $Lists1 2 and 3 should be identical and $List4 differs
    [string[]]$List1  = "AA","BBB"
              $List2  = $List1

    [string[]]$List3  = "AA"
              $List3 += "BBB"

    [string[]]$List4  = $List3
              $List4 += "CCCC"

    "--------"
    "Checking for Equality of the Lists using the -EQ comparison operator (why do all fail--- when only List4 should fail)"
    "--------"
    if ($List1 -eq $List1) {"List 1 and 1 are equal"} else {"List 1 and 1 are NOT equal"}
    if ($List1 -eq $List2) {"List 1 and 2 are equal"} else {"List 1 and 2 are NOT equal"}
    if ($List1 -eq $List3) {"List 1 and 3 are equal"} else {"List 1 and 3 are NOT equal"}
    if ($List1 -eq $List4) {"List 1 and 4 are equal"} else {"List 1 and 4 are NOT equal"}
    ""
    ""
    "--------"
    "Checking using Compare-object (operates as expected - only List4 Differs)"
    "--------"
    if ((compare-object $List1 $List1) -eq $null) {"List 1 and 1 are equal"} else {"List 1 and 1 are NOT equal"}
    if ((compare-object $List1 $List2) -eq $null) {"List 1 and 2 are equal"} else {"List 1 and 2 are NOT equal"}
    if ((compare-object $List1 $List3) -eq $null) {"List 1 and 3 are equal"} else {"List 1 and 3 are NOT equal"}
    if ((compare-object $List1 $List4) -eq $null) {"List 1 and 4 are equal"} else {"List 1 and 4 are NOT equal"}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gene Lowy
  • 15
  • 5

2 Answers2

0

Let me explain it to you with an example:

$a1 = @(1, 2, 3, 4, 5)
$b1 = @(1, 2, 3, 4, 5, 6)
$c = Compare-Object -ReferenceObject (1..5) -DifferenceObject (1..6) -PassThru

$c will be 6.

That's what compare object does

Where -EQ only checks like if the left-hand side is equal to the right or not. It results in a boolean value.

Example

$DNS = (Test-Connection www.google.com -quiet)
If($DNS -eq "True") {Write-Host "The Internet is available"}
ElseIf($DNS -ne "True") {Restart-Service dnscache}
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ranadip Dutta
  • 8,857
  • 3
  • 29
  • 45
  • Thanks Ranadip - My problem - and the reason for this query is that I thought EQ worked like you stated and expected that EQ would check if the left-hand equals the right hand operand - but that does not seem to work as expected for arrays. for example ... try this [string[]]$List1="A","B" [string[]]$List2="A","B" if ($List1 -eq $List1) {"List1 ---$List1--- Equals itself"} else {"List1 ---$List1--- DOES NOT Equal itself"} if ($List1 -eq $List2) {"List1 ---$List1--- and 2 ---$List2--- are equal"} else {"List1 ---$List1--- and 2 ---$List2--- are NOT equal"}` – Gene Lowy Dec 09 '16 at 13:29
  • Yes.. I second you.. eq has some limitations also. – Ranadip Dutta Dec 09 '16 at 13:39
  • But if you do remove one element from the list. Then it will take. The reason being you are converting an array to string as a Type Cast and EQ cannot handle that. Try this. It will work . `[string[]]$List1="A" [string[]]$List2="A" if ($List1 -eq $List1) {"List1 ---$List1--- Equals itself"} else {"List1 ---$List1--- DOES NOT Equal itself"} if ($List1 -eq $List2) {"List1 ---$List1--- and 2 ---$List2--- are equal"} else {"List1 ---$List1--- and 2 ---$List2--- are NOT equal"}` – Ranadip Dutta Dec 09 '16 at 14:06
0

Taken from this answer - which is certainly worth reading as it very elequently explains your question:


When the -eq operator is used between two array variables, things are a bit different. PowerShell will, in fact, enumerate only the array on the left side and compare each item to the array on the right side as a whole. The result will be an array of matching items or nothing at all when there are no matches.

Compare-Object will return an array of differences between the two arrays or $null when the arrays are equal. More precisely, the resulting array will contain an object for each item that exists only in one array and not the other.

Community
  • 1
  • 1
henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
  • I think I have it now - thanks. In summary THE -EQ operator only returns a status of TRUE when There is only one element in the 2nd operand - and .... - and - ANY element in the first operand has to match THE SINGLE ELEMENT in the 2nd operand. So if List1= A, B and List2=A then List1 -eq List2 returns TRUE. if List1= A and List2=A, B then List1 -eq List2 returns FALSE – Gene Lowy Dec 09 '16 at 13:19