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

如何按参考对象顺序排序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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:22:53