如何按参考对象顺序排序Compare-Object结果并高效对比CNC文件
问题
我有两个CNC控制器文件需要对比,用$Diffs = Compare-Object -ReferenceObject $CFFC -DifferenceObject $CSFC -IncludeEqual能拿到对比结果,但结果是按SideIndicator排序的,没法按照参考对象($CFFC)的文件顺序输出变更与原始内容的总结。我想要的输出格式要对应参考对象的顺序(示例如下),目前用foreach循环实现但速度极慢,同时还要处理输入文件中行重复次数比参考文件多的场景,想问问有没有更高效稳健的实现方式。
示例输入
... Reference Object |Input Object | X-17.7936 Y-7.4805 C-273.65 |X-17.7936 Y-7.4805 C-273.65 X-17.9524 Y-4.9136 Z2.9619 C273.67 |X-17.9524 Y-4.9136 Z2.9619 C273.67 ...
期望输出
X-17.7936 Y-7.4805 C-273.65 | X-17.9524 Y-4.9136 Z2.9619 C273.67 | ... X9.8277 Y-10.8339 Z7.404 A-29.001 C274.152|Changed ...
现有低效实现代码
$NewArr=@() foreach($line in $csfc){ $ChangeStatus = ($Diffs -match [regex]::Escape($line)).SideIndicator $LineStatus = "" | Select LINE, TYPE if ($ChangeStatus -eq "=="){ $LineStatus.line = $line $LineStatus.Type = $true } else{ $LineStatus.line = $line $LineStatus.Type = $false } $newarr += $LineStatus }
高效实现方案
核心优化思路
现有代码慢的根源是循环内反复对$Diffs执行正则匹配查询,时间复杂度为O(n*m)(n为行数,m为$Diffs长度)。换成哈希表预存行计数后,查询时间降至O(1),整体复杂度变为O(n+m),同时能自然处理重复行的匹配问题。
具体实现代码
# 1. 统计参考对象($CFFC)每行的出现次数 $refLineCounts = @{} foreach ($line in $CFFC) { $refLineCounts[$line] = ($refLineCounts[$line] ?? 0) + 1 } # 2. 统计差异对象($CSFC)每行的出现次数 $diffLineCounts = @{} foreach ($line in $CSFC) { $diffLineCounts[$line] = ($diffLineCounts[$line] ?? 0) + 1 } # 3. 按参考对象顺序生成主结果 $outputLines = foreach ($line in $CFFC) { # 减少当前行的计数,处理重复行匹配 $refLineCounts[$line]-- $currentDiffCount = $diffLineCounts[$line] ?? 0 $diffLineCounts[$line] = [math]::Max(0, $currentDiffCount - 1) # 判断行状态 $status = if ($currentDiffCount -gt 0) { "" } else { "Changed" } # 格式化输出对齐 "{0,-45}|{1}" -f $line, $status } # 4. 补充差异对象中多余的行(参考对象没有但输入多出来的) foreach ($entry in $diffLineCounts.GetEnumerator()) { if ($entry.Value -gt 0) { for ($i = 0; $i -lt $entry.Value; $i++) { "{0,-45}|Added" -f $entry.Name } } } # 输出最终结果 $outputLines
代码说明
- 用两个哈希表分别统计两行文件的行出现次数,解决重复行的匹配错位问题。
- 遍历参考对象时,每处理一行就减少对应计数,确保重复行能逐一匹配。
- 最后补充处理差异对象中多余的行,标记为
Added。 - 用字符串格式化
-f实现和期望输出一致的对齐效果。
内容的提问来源于stack exchange,提问作者TheBends
相关产品推荐
相关产品推荐

