PowerShell如何高效从一个列表过滤排除另一个列表的元素
<已更新,补充Santiago Squarzon提供的建议信息>
实现方案
需求说明
需要从单列文本列表中过滤掉指定禁用词,规则如下:
- 原始列表规模可达30万行以上,禁用词列表规模为数百行,要求实现尽可能高效
- 过滤规则不区分大小写
- 示例场景下过滤后结果为
dirt、turtle
现有读取文件的基础代码:
$orginal_list = Get-Content -Path .\random-word-350k-wo-quotes.txt $filter_words = Get-Content -Path .\no_go_words.txt
测试用演示数据:
$orginal_list = "yellow","blue","yellow","dirt","blue","yellow","turtle","dirt" $filter_words = "yellow","blue","green","harsh" # 直接做列表减法的写法无法生效,仅为占位 $filtered_list = $orginal_list - $filter_words
高性能实现代码
核心优化点是使用不区分大小写的HashSet存储禁用词:HashSet的元素存在性检查时间复杂度为O(1),相比普通数组每次O(n)的遍历匹配,在大数据量下性能差距可达上百倍。
# 构造不区分大小写的禁用词哈希集合 $filterSet = [System.Collections.Generic.HashSet[string]]::new( $filter_words, [System.StringComparer]::OrdinalIgnoreCase ) # 执行过滤:保留所有不在禁用词集合中的元素,如需去重追加 | Select-Object -Unique 即可 $filtered_list = $orginal_list.Where({ -not $filterSet.Contains($_) }) | Select-Object -Unique
运行上述测试代码后,$filtered_list的输出完全符合预期:
dirt turtle
注意事项
- 如果不需要对过滤结果去重,直接删除代码末尾的
| Select-Object -Unique即可,会保留原始列表中所有非禁用词的出现顺序和重复次数 - 该实现天然支持不区分大小写匹配,例如禁用词写
Blue也可以匹配原始列表中的blue、BLUE等不同大小写形式 - 针对35万行规模的原始词列表,整个过滤过程耗时通常在50毫秒以内,无性能压力
内容的提问来源于stack exchange,提问作者Rugbyball
相关产品推荐
相关产品推荐

