MicrosoftDocs / PowerShell-Docs

The official PowerShell documentation sources
https://learn.microsoft.com/powershell
Other
2k stars 1.58k forks source link

a more common compare two sets of objects example #5824

Closed jszabo98 closed 4 years ago

jszabo98 commented 4 years ago

I'm surprised there's not already an example like this comparing two sets of objects. This is a common point of confusion . You usually need to specify -property when comparing objects.

$a = [pscustomobject]@{name='joe'}
$b = [pscustomobject]@{name='joey'}

compare-object $a $b  # no output

compare-object $a $b -property name

name SideIndicator
---- -------------
joey =>
joe  <=

Actually, I don't even think this is true:

The result of the comparison indicates whether a property value appeared only in the reference object (<=) or only in the difference object (=>). If the IncludeEqual parameter is used, (==) indicates the value is in both objects.

$a = [pscustomobject]@{name='joe';address='here'}   
$b = [pscustomobject]@{name='joey'}              
compare-object $a $b  # no output

It looks to me that example 4 is just converting each array to strings, and then comparing the string versions.


Document Details

Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

sdwheeler commented 4 years ago

You are half right about the string comparison. If you compare two complex objects without specifying one or more properties, the cmdlet tries several different methods to do the comparison. It checks for an IComparable interface, it checks for object-specific Equals methods. When those fail, it resorts to comparing the ToString() results of the objects.

jszabo98 commented 4 years ago

You are half right about the string comparison. If you compare two complex objects without specifying one or more properties, the cmdlet tries several different methods to do the comparison. It checks for an IComparable interface, it checks for object-specific Equals methods. When those fail, it resorts to comparing the ToString() results of the objects.

True, but objects having a meaningfull .compareto() or .equals() method seem rare. The only common example I can come up with is the output of get-date (datetime), not the output of get-process, get-childitem, get-aduser, etc.

jszabo98 commented 4 years ago

Note also that when comparing text files, compare-object sorts them first. So two files with lines in a different order will come out equal.

$file1 = 'line one','line two','line three'
$file2 = 'line three','line two','line one'
compare-object $file1 $file2 -IncludeEqual

InputObject SideIndicator
----------- -------------
line two    ==
line one    ==
line three  ==
jszabo98 commented 4 years ago

I still think this document is confusing. This statement is patently false, unless the -property parameter is being used. Many people assume that all properties are being compared, instead of the string version of the object in most cases, including a process object.

"The result of the comparison indicates whether a property value appeared only in the reference object (<=) or only in the difference object (=>)."

sdwheeler commented 4 years ago

@jszabo98 Would you be willing to submit a PR with the changes you would like to see?