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

PSObject去重问题:Sort-Object处理重复数据失效求助

PowerShell哈希表数组去重问题解决

问题描述

我有一个包含重复条目的哈希表数组$ExistPreAnalysis,填充代码如下:

foreach ($all in $allFiles) {
    $Issql = 'false'

    if ($all.Extension -eq ".sql") {
        $Issql = 'true'  
    }
    $dllpath = Convert-Path $all.PSPath
    $ParentCount = ($dllpath.Split([System.IO.Path]::DirectorySeparatorChar)).count

    for ($i = -2; $i -gt - $ParentCount; $i--) {
        $parentname = $dllpath.Split([System.IO.Path]::DirectorySeparatorChar)[$i]
        foreach ($r in $resultarray) {
            if ($parentname -match $r.PackageName) {
                foreach ($fil in $r.files) {
                    $dll_name = ($fil.Split([System.IO.Path]::DirectorySeparatorChar)[-1])
                    if ($dll_name -like '${TargetRootFolder}*') {
                        $dll_name = $dll_name.Replace('${TargetRootFolder}', '')
                    }

                    if ($Issql -eq 'true') {
                        $nameTocompare = $all.name -replace ("%20", " ")
                    }
                    else {
                        $nameTocompare = $all.name
                    }

                    if ($nameTocompare -match $dll_name) {
                        $ExistPreAnalysis += @{
                            PackageName = $r.PackageName 
                            DllName     = $dll_name
                            Patch       = $r.PatchNumber
                        }       
                    }
                }
            }  
        }
    }
}

填充后$ExistPreAnalysis包含18条数据(实际应为9条唯一条目),重复的条目示例如下(每条Patch值对应重复一次):

Name                           Value
----                           -----
DllName                        Pulling AD_Domain_Stored Procedures_PullAD-sp.sql
Patch                          1448763
PackageName                    IDUDatabase
DllName                        Pulling AD_Domain_Stored Procedures_PullAD-sp.sql
Patch                          1485533
PackageName                    IDUDatabase
...(剩余重复条目省略)

我尝试了以下命令处理,但仅返回1条数据:

$ExistPreAnalysis = $ExistPreAnalysis | sort-Object -Unique -Property DllName, Patch, PackageName | Group-Object DllName | Where-Object { $_.Count -gt 1 } |  ForEach-Object { $_.Group }

问题原因

  1. 数据类型不匹配:$ExistPreAnalysis是哈希表(Hashtable)数组,而非PSObject。Sort-Object -Unique对哈希表的去重逻辑是比较对象引用,而非键值对内容,因此无法正确识别重复的哈希表条目。
  2. 过滤逻辑错误:后续的Group-Object DllName | Where-Object { $_.Count -gt 1 }是筛选出现多次的分组,这会丢弃已去重的唯一条目,最终只保留重复组内的第一个元素。

正确解决方案

方案1:转换为PSObject后去重

先将哈希表数组转换为自定义PSObject,再基于属性进行去重:

# 转换为PSObject并去重
$ExistPreAnalysis = $ExistPreAnalysis | ForEach-Object { [PSCustomObject]$_ } |
                    Sort-Object -Property DllName, Patch, PackageName -Unique

方案2:用Group-Object直接去重

通过分组后提取每组的第一个元素,实现去重:

$ExistPreAnalysis = $ExistPreAnalysis | Group-Object -Property DllName, Patch, PackageName |
                    ForEach-Object { $_.Group[0] }

方案3:从源头避免重复

在填充数组时就检查条目是否已存在,避免添加重复项,提升整体效率:

# 修改填充代码中的添加逻辑
if ($nameTocompare -match $dll_name) {
    $newEntry = @{
        PackageName = $r.PackageName 
        DllName     = $dll_name
        Patch       = $r.PatchNumber
    }
    # 检查是否已有相同条目
    $isDuplicate = $ExistPreAnalysis | Where-Object {
        $_.PackageName -eq $newEntry.PackageName -and
        $_.DllName -eq $newEntry.DllName -and
        $_.Patch -eq $newEntry.Patch
    }
    if (-not $isDuplicate) {
        $ExistPreAnalysis += $newEntry
    }
}

验证结果

执行上述任一正确方案后,$ExistPreAnalysis将包含9条唯一数据,每条对应不同的Patch值。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:42:30