4

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.

2
  • While the documentation doesn't describe your exact question very well, I strongly recommend reading it. This is the difference between an array comparison and a string comparison (type coercion). Commented Jun 10, 2018 at 4:10
  • Yeah, sadly the docs just tells short explanation, without explaining how does it work. Reading all answers, I think the same way javascript does comparison #OOT. Commented Jun 10, 2018 at 4:39

2 Answers 2

6

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

Sign up to request clarification or add additional context in comments.

4 Comments

Nice, I didn't know about $OFS. It appears to be $null by default though.
@Tomalak It's an automatic variable. Check out the docs
@TheIncorrigible1 Well, I checked and it's totally not in the link you just gave.
@Tomalak My bad, wrong link. It's actually filed under preference variables.
4

-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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.