PowerShellの基本的なことがわかってなかったシリーズ第四弾です。
比較演算子についてあれやこれやと書いていきます。
とはいえ半分くらいは愚痴かも...
基本的には-eq
演算子について触れますが他の演算子も大体同様なはず。
1.文字列の比較がデフォルトでIgnore Caseである
ずっと思い込みで文字列の比較はCase Sensitiveだと思っていました。
でも実際には、
PS C:\> "abc" -eq "aBc" True
な感じでIgnore Caseです。
Case Sensitiveに比較をする場合は-ceq
演算子を使う必要があります。
また、-ieq
とIgrore Caseを明示した演算子もあります。
PS C:\> "abc" -ceq "aBc" False PS C:\> "abc" -ieq "aBc" True
ちなみに-ne
、-ge
、-gt
、-le
、-lt
、-like
、-notlike
、-match
、-notmatch
、-contains
、-notcontains
、-replace
、-split
演算子も同様です。
個人的にはこの仕様には納得がいっていません。
例えば"abc".Equals("aBc")
な風に普通にEqualsメソッドが使えるシェルで、当然この結果はCase SensitiveなのでFalse
を返すのにもかかわらず-eq
演算子はIgnore Caseってのは.NETの世界観にそぐわない気がして仕方がないのです。
とはいえ、実際にこういう仕様になってしまっているので割り切るしかないのですが...
文字列比較のより詳しい話はぎたぱそさんのこちらのエントリを見ていただくほうが良いかと思います。
2.左辺値の型に変換されて比較される
これは仕方ない仕様だとは思います。
比較する左辺と右辺の型が違う場合、右辺値の型を左辺に合わせる様に変換を試みてから比較を行うというものです。
極端な例を出すと、
PS C:\> 0 -eq "" True
なんてことが起きます。
これは実際には以下の様な変換が行われて比較されます。
PS C:\> 0 -eq [int]""
[int]""
は0
に変換されるため、0 -eq [int]""
は0 -eq 0
となりTrue
が返されることになります。
ちなみに逆の場合は、
PS C:\> "" -eq 0 ↓ PS C:\> "" -eq [string]0 ↓ PS C:\> "" -eq "0" False
となります。
3.比較演算子がFilterとして作用する場合がある
左辺値に配列が来た場合に比較演算子がFilterとして機能します。
以下に例を挙げると、
PS C:\> @("a", "b", "c") -eq "A" a
とFalse
を返さずフィルタされた結果の"a"
が返されます。
牟田口さんのこちらのエントリにもありますが、配列のNULLチェックを行う際はこの仕様に注意する必要があります。
しかし...これは本当にどうしてこうなった!?としか思えないんですがどうなんですかね?
比較は比較、フィルタはフィルタで個別に演算子を分けるべきだったんじゃないのかと思うんですけど一体何があったんでしょうか...