0

我正在尝试编写一个从 DataTable 中过滤掉重复条目的函数。我的代码工作正常,但前提是行:3-4 不在注释中。我尝试将 $tbl1 变量的默认范围更改为全局,但没有帮助。

我在做什么?代码如下。

Function RemoveDuplicates
{
    #$tbl1 | export-csv ".\tmp.csv"   #Code works perfectly when you uncomment these two lines.
    #$tbl1 = import-csv ".\tmp.csv"   #

    $t_tbl = $tbl1 | Sort-Object -Property Prop3 -Unique
    $duplicates = Compare-Object -ReferenceObject $tbl1 -DifferenceObject $t_tbl -Property Prop3
    #$duplicates

    write-host "tbl1 count: $($tbl1.Rows.Count)"
    write-host "t_tbl count: $($t_tbl.Count)"
    write-host "duplicates count: $(@($duplicates).Count)"

    write-host "Found $($tbl1.Rows.Count) entries. $($t_tbl.Count) entries have unique Prop3. Duplicates: $(@($duplicates).count)"
}
    $tbl1 = New-Object System.Data.DataTable
    $col1 = New-Object System.Data.DataColumn Prop1,([string])
    $col2 = New-Object System.Data.DataColumn Prop2,([string])
    $col3 = New-Object System.Data.DataColumn Prop3,([string])
    $tbl1.Columns.Add($col1)
    $tbl1.Columns.Add($col2)
    $tbl1.Columns.Add($col3)

    $row = $tbl1.NewRow()
            $row.Prop1 = "Jane"
            $row.Prop2 = "Doe"
            $row.Prop3 = "jane.doe@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Jack"
            $row.Prop2 = "Awesome"
            $row.Prop3 = "jane.doe@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Julia"
            $row.Prop2 = "Whatever"
            $row.Prop3 = "test@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Mr"
            $row.Prop2 = "ScriptGuy!"
            $row.Prop3 = "scriptguy@domain.local"
        $tbl1.Rows.Add($row)
    $row = $tbl1.NewRow()
            $row.Prop1 = "Mrs"
            $row.Prop2 = "ScriptLady!"
            $row.Prop3 = "scriptlady@domain.local"
        $tbl1.Rows.Add($row)

    RemoveDuplicates

谢谢

4

1 回答 1

0

不幸的是,它与范围无关。它与数据类型有关。

这可能令人沮丧:

Compare-Object 接受两个数组并枚举它们以查找不同的项目。作为测试,让我们看看 PowerShell 如何枚举$tbl1. 在foreach对象和数组方面,关键字的作用与参数解析非常相似。

foreach($row in $tbl1) { $_ }

输出为空白。这是因为它被视为单个对象,而不是集合。PowerShell cmdlet 参数解析不会枚举默认集合变量。但是,如果我们通过管道推送表格,

$tbl1 | % { $_ }

我们得到每一行的数据:

Prop1                                                       Prop2                                                      Prop3                                                     
-----                                                       -----                                                      -----                                                     
Jane                                                        Doe                                                        jane.doe@domain.local                                     
Jack                                                        Awesome                                                    jane.doe@domain.local                                     
Julia                                                       Whatever                                                   test@domain.local                                         
Mr                                                          ScriptGuy!                                                 scriptguy@domain.local                                    
Mrs                                                         ScriptLady!                                                scriptlady@domain.local  

然后,该行:$t_tbl = $tbl1 | Sort-Object -Property Prop3 -Unique将创建一个从 Sort object 命令输出的对象数组,事实上,如果我们执行以下命令$t_tbl.GetType().FullName:$表 | 选择对象-First 1 | % { $ .GetType().FullName },我们看到它是一个System.Object[](一个数组),其中每个项目都是一个System.Data.DataRow实例。 $tbl1然而是一个System.Data.DataTable实例,而不是一个数组。

所以,它什么时候Compare-Object起作用,它是将一组数据行与一个单一的数据表进行比较。$duplicates当这些行被注释掉时,请记住这一点。

# Output of Compare-Object -ReferenceObject $tbl1 -DifferenceObject $t_tbl -Property Prop3
Prop3                   SideIndicator
-----                   -------------
jane.doe@domain.local   =>           
scriptguy@domain.local  =>           
scriptlady@domain.local =>           
test@domain.local       =>           
                        <=           

参数ReferenceObjectDifferenceObject是期望的数组。当我们传递DifferenceObject一个数组时,我们传递ReferenceObject了一个值,cmdlet 将其视为大小为 1 的数组。

DataTable 没有Prop3要比较的。

当您取消注释这些行时,您将 CSV 文件的内容拉回,您不会获得 DataTable 对象。System.Management.Automation.PSCustomObject您将根据 CSV 文件中的列获得具有成员属性的实例数组。在这种情况下,Compare-Object 现在有两个要比较的数组,它们都与具有 Prop3 属性的对象进行比较。

如果您需要做的只是获取数据表中某一列的唯一值,请尝试以下操作:

$tbl1 | Select-Object -ExpandProperty Prop3 | Get-Unique
于 2013-11-13T03:08:28.343 回答