You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PowerShell中对比两个HashSet结果为空:跨共享文件名匹配异常排查

问题排查:HashSet求交集返回空结果的修复

我用两个HashSet分别存储不同文件共享的文件名,目标是找出两者的共同文件名存入第三个HashSet $setDiff,要求结果无重复且支持任一集合为空的场景。但实际运行时,明明存在匹配的文件名,却偶尔返回空结果。

初始化代码

$setOrig = New-Object System.Collections.Generic.HashSet[System.String]
$setOrigNames = New-Object System.Collections.Generic.HashSet[System.String]
$setArchived = New-Object System.Collections.Generic.HashSet[System.String]
$setArchivedNames = New-Object 'System.Collections.Generic.HashSet[System.String]'
$setDiff = New-Object System.Collections.Generic.HashSet[System.String]
$origNamePathPair = New-Object 'System.Collections.Generic.Dictionary[string,string]'
$archNamePathPair = New-Object 'System.Collections.Generic.Dictionary[string,string]'

原核心逻辑代码

$setOrig = Get-ChildItem  -Path $_.FullName -Recurse -Include("*.png")$setArchived | 
ForEach-Object { $archNamePathPair[$_.BaseName] = $setArchived[$i], $i++ }

$idx = 0
$setOrig | ForEach-Object { $origNamePathPair[$_.BaseName] = $setOrig[$idx], $idx++ 
 }
$setOrigNames = $setOrig | ForEach-Object {$_.BaseName}       
$setArchivedNames = $setArchived | ForEach-Object {$_.BaseName}
   
    $hash1 = [System.Collections.Generic.HashSet[string]]::new(
        [string[]] ($setOrigNames),
        [System.StringComparer]::InvariantCulture)

    $hash2 = [System.Collections.Generic.HashSet[string]]::new(
        [string[]] ($setArchivedNames),
        [System.StringComparer]::InvariantCulture)
    
    $setDiff = @(
    $hash2.Where{ $hashset1.Contains($_) }
    )

问题根源

  1. 变量名拼写错误:核心逻辑中使用了未定义的$hashset1,正确变量名应为$hash1,这直接导致无法匹配元素
  2. 语法混乱:Get-ChildItem语句拼接错误,$setOrig和$setArchived未被正确初始化
  3. HashSet访问错误:HashSet不支持索引访问(如$setArchived[$i]),此类操作会返回空值或引发异常
  4. 类型不符合需求:最终将$setDiff赋值为数组,而非要求的HashSet类型

修复后的核心逻辑

# 正确获取源文件集合(需确保$_指向目标目录)
$setOrig = Get-ChildItem -Path $_.FullName -Recurse -Include "*.png" | Select-Object -ExpandProperty FullName
# 替换$archivedPath为你的归档文件共享路径
$setArchived = Get-ChildItem -Path $archivedPath -Recurse -Include "*.png" | Select-Object -ExpandProperty FullName

# 构建文件名-路径映射(修复索引访问问题)
$setOrig | ForEach-Object {
    $file = Get-Item $_
    $origNamePathPair[$file.BaseName] = $file.FullName
}

$setArchived | ForEach-Object {
    $file = Get-Item $_
    $archNamePathPair[$file.BaseName] = $file.FullName
}

# 提取文件名集合
$setOrigNames = $setOrig | ForEach-Object { (Get-Item $_).BaseName }
$setArchivedNames = $setArchived | ForEach-Object { (Get-Item $_).BaseName }

# 创建指定字符串比较规则的HashSet
$hash1 = [System.Collections.Generic.HashSet[string]]::new(
    [string[]]$setOrigNames,
    [System.StringComparer]::InvariantCulture
)

$hash2 = [System.Collections.Generic.HashSet[string]]::new(
    [string[]]$setArchivedNames,
    [System.StringComparer]::InvariantCulture
)

# 求交集并保持HashSet类型
$hash2.Where({ $hash1.Contains($_) }) | ForEach-Object {
    [void]$setDiff.Add($_)
}

简化优化方案

直接利用HashSet内置的IntersectWith方法求交集,代码更简洁高效:

# 初始化HashSet并传入文件名集合
$hash1 = [System.Collections.Generic.HashSet[string]]::new($setOrigNames, [System.StringComparer]::InvariantCulture)
$hash2 = [System.Collections.Generic.HashSet[string]]::new($setArchivedNames, [System.StringComparer]::InvariantCulture)

# 直接求交集,结果存入$hash1
$hash1.IntersectWith($hash2)
# 赋值给目标HashSet
$setDiff = $hash1

内容的提问来源于stack exchange,提问作者Newborn

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.25 12:58:20