Finding an item in an array
Finding an item in an array
$LogsPath = '\someserversomepath*'
$LogsProperties = Get-ChildItem -Path $LogsPath -recurse |
Select-String -Pattern '[a-z]' |
Select-Object -Property Filename, Path, Line
$Array = @()
$LogsProperties | foreach
$Array += $LogsProperties
The query above will create an array with the following values
(dashes are tabs/columns)
Filename--------------------------Path--------------------------------------------------------------Line
FName1 LName1.txt-----------\someserversomepathFName1
LName1.txt-----------XXX Value
FName2 LName2.txt-----------\someserversomepathFName1
LName1.txt-----------YYY Value
FName3 LName3.txt-----------\someserversomepathFName1
LName1.txt-----------ZZZ Value
$Array[0]
Returns:
FName1 LName1.txt-----------\someserversomepathFName1
LName1.txt-----------XXX Value
Can someone tell me how to search for the index of an element using a value
The function below doesn't work for me
$array.indexof('XXX Value')
0 <-- expected result, index of the array
and will return the error below
Method invocation failed because [System.Object] doesn't contain a
method named 'indexof'. At line:20 char:15
+ $array.indexof <<<< ('XXX Value')
+ CategoryInfo : InvalidOperation: (indexof:String) , RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
2 Answers
2
As pointed out in The Incorrigible1's answer, $LogsProperties is already an array, whose elements are [pscustomobject] instances with properties FileName, Path, and Line.
$LogsProperties
[pscustomobject]
FileName
Path
Line
(Your attempt to create $Array from $LogsProperties is not only unnecessary, but also broken, because the elements of $Array all end up referencing the array referenced by $LogsProperties as a whole.)
$Array
$LogsProperties
$Array
$LogsProperties
In order to use the .IndexOf() method on array instances[1], PSv3+ is required.
PSv3+ also allows you to use member enumeration, so you can apply .IndexOf() to $LogsProperties.Line in order to search the array of .Line property values:
.IndexOf()
.IndexOf()
$LogsProperties.Line
.Line
$LogsProperties.Line.IndexOf('XXX Value') # -> 0
In PSv2 you can use a foreach loop to determine the index:
foreach
$i = 0
foreach ($obj in $LogsProperties) if ($obj.Line -eq 'XXX Value') break ; ++$i
if ($i -eq $LogsProperties.Count) $i = -1
# $i now contains the index of the matching element or -1, if not found.
[1] Type System.Array, the base type for all arrays, also has a static .IndexOf() method that is available in PSv2 too. However, given the need to search the .Line property values of the array elements of $LogProperties, that won't help here, unless a separate array with just the .Line property values is constructed first.
System.Array
.IndexOf()
.Line
$LogProperties
.Line
break
[string]$index += "$i"
$index = $null
$i = 0
Thanks, @RobertCotterman. Given that the OP tried to use
.IndexOf(), which only ever returns the first match, I've restricted my foreach loop to the same behavior. In the same vein I've just added code to set $i to -1 if no match is found.– mklement0
Sep 10 '18 at 11:23
.IndexOf()
foreach
$i
-1
So your $logsProperties is already an array. You can filter using Where-Object or the Where array method:
$logsProperties
Where-Object
Where
$logsProperties = Get-ChildItem -Path \someserversomepath* -Recurse |
Select-String -Pattern '[a-z]' |
Select-Object -Property FileName, Path, Line
Filtering:
$logsProperties | Where-Object Line -like '*xxx value*'
or:
$logsProperties.Where$_.Line -like '*xxx value*'
This returns the array value not the index of the result :(
– Byron Madison
Sep 9 '18 at 1:14
@ByronMadison Why do you need the index?
– TheIncorrigible1
Sep 9 '18 at 16:25
I want to call the value of the index, part of a wider plan for the script. I want to get the path and compare it to something else
– Byron Madison
Sep 9 '18 at 22:26
Thanks for contributing an answer to Stack Overflow!
But avoid …
To learn more, see our tips on writing great answers.
Required, but never shown
Required, but never shown
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Utilizing the foreach loop, instead of
breakhe could start another variable as such[string]$index += "$i"to create an array of index's that all contain the search criteria, instead of just the first one. (if that's his goal)... I would also put a$index = $nullunder$i = 0– Robert Cotterman
Sep 10 '18 at 4:43