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

PowerShell中ExpandProperty为何修改源对象?如何规避?

PowerShell展平嵌套对象数组时避免修改源对象的方法

当处理包含嵌套对象数组的对象数组时,使用Select-Object -ExpandProperty看似能实现展平需求,但会意外修改源对象中的嵌套元素——比如执行$obj | Select-Object -Property Name -ExpandProperty Books后,源对象里的每个Book对象会被添加父对象的Name属性,再次执行该命令会报错:

Select-Object : The property cannot be processed because the property "Name" already exists.

为什么会修改源对象?

ConvertFrom-Json生成的是动态的PSCustomObject实例,这类对象允许在运行时添加/修改属性。而Select-Object -ExpandProperty为了性能优化,没有为每个嵌套对象创建新实例,而是直接在原嵌套对象上附加指定的父属性(这里的Name),导致源对象被永久修改。

解决方案:不修改源对象实现展平

以下几种方法可以在不改动源对象的前提下,生成独立的展平结果:

方法1:手动构造新对象(最直观)

通过ForEach-Object遍历每个父对象,再遍历其嵌套的Books数组,为每个Book创建全新的PSCustomObject,同时附加父对象的属性:

$json = '[{"Name":"James","Age":42,"Books":[{"Title":"Consider Phlebas","Author":"Iain M. Banks"},{"Title":"The Player of Games","Author":"Iain M. Banks"}]},{"Name":"Susan","Age":36, "Books":[{"Title":"The Three Body Problem","Author":"Cixin Liu"},{"Title":"The Dark Forest","Author":"Cixin Liu"}]}]'
$obj = $json | ConvertFrom-Json

# 生成独立的展平结果,不修改源对象
$flattened = $obj | ForEach-Object {
    $parentName = $_.Name
    $_.Books | ForEach-Object {
        [PSCustomObject]@{
            Name   = $parentName
            Title  = $_.Title
            Author = $_.Author
        }
    }
}

$flattened | Format-Table

方法2:使用Select-Object的计算属性(更简洁)

通过计算属性强制创建新对象,避免直接修改原嵌套元素:

$flattened = $obj | ForEach-Object {
    $parent = $_
    $parent.Books | Select-Object @{Name='Name'; Expression={$parent.Name}}, Title, Author
}

$flattened | Format-Table

方法3:深拷贝源对象(适合复杂场景)

如果需要多次对源对象执行操作,可以先深拷贝一份,避免影响原数据:

# 通过ConvertTo-Json+ConvertFrom-Json实现深拷贝
$objCopy = $obj | ConvertTo-Json -Depth 10 | ConvertFrom-Json
# 对拷贝后的对象执行操作,不会影响原$obj
$objCopy | Select-Object -Property Name -ExpandProperty Books

验证

执行上述任意方法后,检查源对象的Books属性:

$obj[0].Books | Get-Member -MemberType NoteProperty

会发现源对象的Book元素并没有新增Name属性,命令可以重复执行而不报错。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 02:57:11