Reputation: 909
I created a function to find an item in an array so I can update it.
function Get-ArrayRowIndex {
param(
[parameter(mandatory = $true)][array]$Property,
[parameter(mandatory = $true)][string]$Value
)
#Loop through array,incrementing index until value is found. Jordan wrote this and I refined it.
[int]$index = 0
while ($index -lt ($Property.count)) {
if ($Property[$index] -eq $Value) {
break
}
$index++
}
return [int]$index
}
The problem is when the object is not found the function returns the total number of items in the array. How can I return an error if not found?
Upvotes: 2
Views: 1065
Reputation: 60060
Normally a for
loop is a cleaner approach for this:
function Get-ArrayRowIndex {
param(
[Parameter(Mandatory)]
[array] $Property,
[Parameter(Mandatory)]
[string] $Value
)
for ($i = 0; $i -lt $Property.Count; $i++) {
if ($Property[$i] -eq $Value) {
return $i
}
}
throw "$Value not found in this array."
}
$arr = 0..10
Get-ArrayRowIndex $arr 4 # => returns 4
Get-ArrayRowIndex $arr 11 # => throws "11 not found in this array."
Upvotes: 3
Reputation: 23663
The PowerShell way, using Select-String
:
$Properties = 'One', 'Two', 'Three'
$Value = 'Two'
($Properties | Select-String -SimpleMatch -Pattern $Value).LineNumber
2
Throwing errors:
$Found = $Properties | Select-String -SimpleMatch -Pattern $Value
Switch ($Found.Count) {
0 { Throw "$Value not found" }
1 { $Found.LineNumber }
Default { Throw "More than one $Value found" }
}
Upvotes: 3
Reputation: 438018
If you want to throw an error in case the value isn't found:
function Get-ArrayRowIndex {
param(
[parameter(mandatory = $true)][array]$Property,
[parameter(mandatory = $true)][string]$Value
)
[int]$index = 0
while ($index -lt ($Property.count)) {
if ($Property[$index] -eq $Value) {
# Found -> output the value and return (exit) here.
return $index
}
$index++
}
# Getting here means that the value wasn't found.
throw "'$Value' not found in the given array."
}
Note that you could use the [Array]::FindIndex()
method instead of looping through the array yourself:
# Returns the index if found; -1 otherwise.
[Array]::FindIndex(
$Property,
[Predicate[object]] { $Value -eq $args[0] }
)
[Array].IndexOf()
is another option, but only if case-sensitive string comparison is desired (whereas PowerShell's operators, such as -eq
used above, are case-insensitive by default); e.g., ('FOO', 'bar').IndexOf('foo')
yields -1
(not found) and ('FOO', 'foo').IndexOf('foo')
yields 1
Upvotes: 4