简体   繁体   English

Powershell 从数组列表中删除对象

[英]Powershell Remove objects from an array list

Is there a non for-loop way to remove some items from a arrayList?是否有一种非 for 循环方法可以从 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?我想从 $remoteFiles var.. 中删除上面的输出..是否有一些管道方法可以删除它们?

Assuming all of the following:假设以下所有情况:

  • you do need the results captured in $remotesumerrors separately您确实需要单独在$remotesumerrors捕获的结果
  • that $remoteFiles is a collection of System.IO.FileInfo instances, as output by Get-ChildItem , for instance $remoteFilesSystem.IO.FileInfo实例的集合,例如由Get-ChildItem输出
  • it is acceptable to save the result as an invariably new collection back to $remoteFiles ,将结果作为一个新的集合保存回$remoteFiles是可以接受的,

you can use the .Where() array method as follows (this outperforms a pipeline-based solution based on the Where-Object cmdlet ):您可以使用.Where()数组方法如下(这优于基于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.将集合转换为[System.Collections.Generic.HashSet[T]]是获取一组不同值(删除重复项)的快速便捷的方法,但请注意,生成的哈希集的元素总是无序的,并且使用字符串, 默认情况下,查找区分大小写- 有关更多信息,请参阅此答案

使用Where-Object cmdlet 筛选列表:

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

If it truly was a [collections.arraylist], you could remove an element by value.如果它真的是一个 [collections.arraylist],你可以按值删除一个元素。 There's also .RemoveAt(), to remove by array index.还有 .RemoveAt(),用于按数组索引删除。

[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

Let assume that $remoteFiles is a file object of type System.IO.FileInfo.假设 $remoteFiles 是 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编辑:根据评论更正答案

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM