Search code examples
powershellcomparison

Why does the comparison operator not work after enumeration?


I have pretty simple use case below where I need to find if certain element of Array exists. Why conditional operator in this case is not working?

@("a", "b").Where{$_ -eq "a"} -eq $true

Solution

  • The .Where() array method acts as a filter (just like its cmdlet counterpart, Where-Object), so it returns a subarray[1] of matching elements, not a Boolean.

    For simple equality testing[2], you can use the Boolean -contains operator instead:

    ('a', 'b') -contains 'a' # -> $true
    

    If you do need a more sophisticated, scriptblock-based test via .Where():

    ('a', 'b').Where({ $_ -in 'a', 'z' }, 'First').Count -ne 0
    

    Note the the 'First' argument, which, as an important optimization, makes .Where() return after the first match is found.

    Since the result is always wrapped in an array[1], checking the .Count property is sufficient to determine if a match was found.


    [1] Technically, a collection of type [System.Collections.ObjectModel.Collection[psobject]] is returned.

    [2] Note that PowerShell is case-insensitive by default, but it offers c-prefixed versions of its comparison operators for case-sensitive operations; e.g., -ccontains, or for the equivalent operands-reversed -in operator, -cin.