While PowerShell's -in
/ -contains
operators allow you to test for containment of a given value in a collection (whether a given value is an element of the collection), there is no direct support for getting an element's index using only PowerShell's own features.
For .NET arrays (such as the ones created in your question[1]) you can use their .IndexOf()
instance method, which uses case-SENSITIVE comparison based on the current culture; e.g.:
$array.IndexOf('red') # -> 1; case-SENSITIVE, current-culture comparison
Note that PowerShell itself is generally case-INSENSITIVE, and with -eq
(and in other contexts) uses the invariant culture for comparison.
A case-INSENSITIVE solution based on the invariant culture, using the Array type's static [Array]::FindIndex()
method:
$array = 'blue', 'ReD', 'yellow'
[Array]::FindIndex($array, [Predicate[string]] { 'red' -eq $args[0] }) # -> 1
Note that by delegating to a PowerShell script block ({ ... }
) in which each element ($args[0]
) is tested against the target value with -eq
, you implicitly get PowerShell's case-insensitive, culture-invariant behavior.
Alternatively, you could use the -ceq
operator for case-sensitive (but still culture-invariant) matching.
($args[0].Equals('red', 'CurrentCulture')
would give you behavior equivalent to the .IndexOf()
solution above).
Generally, this approach enables more sophisticated matching techniques, such as by using the regex-based -match
operator, or the wildcard-based -like
operator.
The above solutions find the index of the first matching element, if any.
To find the index of the last matching element, if any, use:
Note: While there is an [Array]::FindAll()
method for returning all elements that meet a given predicate (criterion), there is no direct method for finding all indices.
[1] Note that you do not need @()
, the array-subexpression operator to create an array from individually enumerated elements: enumerating them with ,
, the array constructor operator alone is enough:
$array = 'blue','red','purple','pink'