在Powershell中通过键匹配两个大对象数组的最快方法

时间:2017-02-16 12:28:45

标签: powershell

我有两个通过Import-CSV生成的PowerShell对象数组,我必须通过它们的一个属性匹配它们。具体来说,它是一个1:n的关系,所以目前我正在遵循这种模式:

foreach ($line in $array1) {
    $match=$array2 | where {$_.key -eq $line.key} # could be 1 or n results
    ...# process here the 1 to n lines
}

,这不是很有效(两个表都有很多列),并且花费的时间对我们的需求来说是不可接受的。是否有最快的方式来执行此匹配?

这两个数据源都来自csv文件,因此也欢迎使用其他东西而不是Import-CSV。 感谢

1 个答案:

答案 0 :(得分:3)

标准方法是使用哈希表(或其他语言的字典/地图)索引数据。

function buildIndex($csv, [string]$keyName) {
    $index = @{}
    foreach ($row in $csv) {
        $key = $row.($keyName)
        $data = $index[$key]
        if ($data -is [Collections.ArrayList]) {
            $data.add($row) >$null
        } elseif ($data) {
            $index[$key] = [Collections.ArrayList]@($data, $row)
        } else {
            $index[$key] = $row
        }
    }
    $index
}

$csv1 = Import-Csv 'r:\1.csv'
$csv2 = Import-Csv 'r:\2.csv'

$index2 = buildIndex $csv2, 'key'

foreach ($row in $csv1) {
    $matchedInCsv2 = $index2[$row.key]
    foreach ($row2 in $matchedInCsv2) {
        # ........
    }
}

此外,如果您需要速度并迭代大型集合,请避免|流水线操作,因为它比foreach / while / do 语句慢很多倍。并且不要在代码中使用像where {$_.key -eq $line.key}这样的ScriptBlock,因为与内部的简单代码相比,执行上下文创建会增加一个非常大的开销。