1

Is there a non for-loop way to remove some items from a arrayList?

$remotesumerrors = $remoteFiles | Select-String  -Pattern '^[a-f0-9]{32}(  )' -NotMatch

I want to remove the output of the above from the $remoteFiles var.. is there some pipe way to remove them?

4 Answers 4

1

Assuming all of the following:

  • you do need the results captured in $remotesumerrors separately
  • that $remoteFiles is a collection of System.IO.FileInfo instances, as output by Get-ChildItem, for instance
  • it is acceptable to save the result as an invariably new collection back to $remoteFiles,

you can use the .Where() array method as follows (this outperforms a pipeline-based solution based on the Where-Object cmdlet):

# Get the distinct set of the full paths of the files of origin
# from the Select-String results stored in $remotesumerrors
# as a hash set, which allows efficient lookup.
$errorFilePaths = 
  [System.Collections.Generic.HashSet[string]] $remotesumerrors.Path

# Get those file-info objects from $remoteFiles
# whose paths aren't in the list of the paths obtained above.
$remoteFiles = $remoteFiles.Where({ -not $errorFilePaths.Contains($_.FullName) })

As an aside:

  • Casting a collection to [System.Collections.Generic.HashSet[T]] is a fast and convenient way to get a set of distinct values (duplicates removed), but note that the resulting hash set's elements are invariably unordered and that, with strings, lookups are by default case-sensitive - see this answer for more information.
Sign up to request clarification or add additional context in comments.

Comments

1

If it truly was a [collections.arraylist], you could remove an element by value. There's also .RemoveAt(), to remove by array index.

[System.Collections.ArrayList]$array = 'a','b','c','d','e'


$array.remove

OverloadDefinitions
-------------------
void Remove(System.Object obj)
void IList.Remove(System.Object value)


$array.remove('c')
$array

a
b
d
e

Comments

0

Use the Where-Object cmdlet to filter the list:

$remoteFiles = $remoteFiles |Where-Object { $_ |Select-String -Pattern '^[a-f0-9]{32}(  )' -NotMatch }

7 Comments

hmm they all still seem to be in the remoteFiles var ...
Nice, though I suggest adding -Quiet to optimize the Select-String call. Also worth nothing that the result will be an array (or singe file-info object) - though perhaps @Tony actually meant an array when referring to "arrayList" rather than a System.Collections.ArrayList instance, specifically.
oh how do I do that where with -ne ?
It might just be a typo, but be aware that if you implement the filter like you did with your original code sample i.e ( $remotesumerrors = $remoteFiles | etc. } $remoteFiles will remain unchanged because the new filtered arraylist is being saved to "$remotesumerrors". You'd have to use the same variable name like mathias did in his answer above.
@Tony: Where-Object { -not ($_ |Select-String -Quiet -NotMatch -Pattern '^[a-f0-9]{32}( )') }
|
0

Let assume that $remoteFiles is a file object of type System.IO.FileInfo. I also assume that you want to filter based on filename.

$remotesumerrors = $remoteFiles.name | Select-String  -Pattern '^[a-f0-9]{32}' -NotMatch

What are trying to do with "( )" or what is query that you want to do.

edit: corrected answer based on comment

3 Comments

[a-f0-9] is totally valid. So is [a-f][0-9]. But they are doing diff things. First one only matches a single character that could be any letter a - f or any num 0-9, your version matches two adjacent characters where the first is a-f and the second is a num 0-9
@diopside I will give you that but what is "( )".
that's a good question. im not sure in this context. ive used something like that in a regex split operation to shift/pad the resulting list based on the presence of spaces in the string, but not sure what its doing here. Ive only used the select-string cmd once so i need to read up on it

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.