Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare string vs array

Tags:

powershell

I'm new to PowerShell script. This is the question that comes when I'm creating test using pester. The question is about comparing array vs string as follows:

@('hello', 'world') -eq 'hello world' # returns nothing
'hello world' -eq @('hello', 'world') # returns true

I will appreciate if someone can tell me the difference.

like image 963
iroel Avatar asked Dec 23 '22 06:12

iroel


2 Answers

PowerShell operators follow the "left hand rule". In other words, the type of the object on the LHS determines how the comparison is done. If the LHS is an array, then the right hand side will be compared to each element of RHS array. If there are matches, then the operator returns the matching elements. if there are no matches, then the operator returns nothing. On the other hand, if the LHS is a string, then the right hand side will be converted to a string and the comparison is done. An array is converted to a string by doing the equivalent of $array -join $OFS. $OFS (output field separator) is a builtin variable that defaults to " ". This is why your second comparison succeeds @("Hello", "world") gets converted to "Hello world".

like image 76
Bruce Payette Avatar answered Dec 25 '22 18:12

Bruce Payette


-eq returns different things when applied to different types of values.

1,2,3,4,1 -eq 1     # returns @(1, 1)

So when applied to an array on the left-hand side, it returns all elements from that array that are equal to the right-hand side operand. It works like a filter on arrays (the same applies to other comparison operators like -ne, -gt, etc.)

@('hello', 'world') -eq 'hello world' # returns nothing

Naturally.


When -eq is applied to a single value on the left-hend side, it returns $true or $false depending on whether the right-hand side is equal to it.

Type conversion takes place. For example, if the left-hand side is a string, the right-hand side is converted to a string, too.

Arrays are converted to string by converting all their elements to string and joining them with a single space by default (the character used can be changed by using a different $OFS - see MSDN, Powershell Team Blog).

'hello world' -eq @('hello', 'world')   # returns true

Naturally. But:

'hello world' -eq @('hello ', 'world')  # returns false, note the space

Use .Equals() to prevent that.

'hello world'.Equals( @('hello', 'world') )  # returns false
(1).Equals("1")                              # false, too
like image 25
Tomalak Avatar answered Dec 25 '22 18:12

Tomalak