我有两个通过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。 感谢
答案 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,因为与内部的简单代码相比,执行上下文创建会增加一个非常大的开销。