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

PowerShell中PSCustomObject仅保留最后写入值问题求助

问题分析与解决

核心结论

PSCustomObject的使用方式本身是合适的,问题出在变量赋值逻辑上——你每次匹配时都直接覆盖了$result变量,没有把新创建的对象添加到集合中,所以最后只保留了最后一组匹配结果。

错误原因

代码中每次进入if分支时,执行的是$result = [pscustomobject]@{...}:这会让$result变量指向新创建的对象,之前存储的匹配对象会被直接丢弃,自然只剩最后一次的结果。

修正方案

需要先初始化一个空集合(数组或泛型列表),每次匹配时把新的PSCustomObject添加到集合里,而非覆盖变量。

方案1:使用数组(适合小数据量场景)

先初始化空数组,匹配时用+=操作添加元素:

# 初始化空数组存储结果
$result = @()
for ($i = 0; $i -lt $array.length; $i++) {
    $cfID = $array[$i].substring(65, 16)
    for ($j = 0; $j -lt $slotnames.length; $j++) {
        if ($slotnames[$j].deviceID.substring(22, 16) -eq $cfID) {
            # 向数组添加新对象,而非覆盖变量
            $result += [pscustomobject]@{
                result1 = $SlotNames[$j].deviceID
                result2 = $SlotNames[$j].Location
                result3 = $array[$i].substring(1, 19)
            }
            break
        } 
        else {
            Write-Host 'No match!'
        } 
    }
}

方案2:使用泛型列表(适合大数据量,效率更高)

+=操作数组时会每次创建新数组,数据量大时性能损耗明显,推荐用泛型列表:

# 初始化泛型列表存储结果
$resultList = [System.Collections.Generic.List[PSObject]]::new()
for ($i = 0; $i -lt $array.length; $i++) {
    $cfID = $array[$i].substring(65, 16)
    for ($j = 0; $j -lt $slotnames.length; $j++) {
        if ($slotnames[$j].deviceID.substring(22, 16) -eq $cfID) {
            # 向列表添加新对象
            $resultList.Add([pscustomobject]@{
                result1 = $SlotNames[$j].deviceID
                result2 = $SlotNames[$j].Location
                result3 = $array[$i].substring(1, 19)
            })
            break
        } 
        else {
            Write-Host 'No match!'
        } 
    }
}
# 可选:将列表转为数组(如需保持数组格式)
$result = $resultList.ToArray()

额外优化建议

嵌套循环的时间复杂度较高(O(n*m)),如果数组元素较多,可以先把$slotnames转换为哈希表,用匹配的ID作为键,将时间复杂度降到O(n):

# 预先构建slotnames的哈希表,key为deviceID截取的16位字符串
$slotHash = @{}
foreach ($slot in $slotnames) {
    $key = $slot.deviceID.substring(22, 16)
    $slotHash[$key] = $slot
}

$result = @()
foreach ($item in $array) {
    $cfID = $item.substring(65, 16)
    if ($slotHash.ContainsKey($cfID)) {
        $slot = $slotHash[$cfID]
        $result += [pscustomobject]@{
            result1 = $slot.deviceID
            result2 = $slot.Location
            result3 = $item.substring(1, 19)
        }
    }
    else {
        Write-Host 'No match!'
    }
}

内容的提问来源于stack exchange,提问作者Lando

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 13:41:11