我正在尝试获取类似于以下内容的 PSObject 数组
@{BakId=27; Name=DB_A; Lsn=123; File=A_01; Size=987}
@{BakId=28; Name=DB_B; Lsn=456; File=B_01; Size=876}
@{BakId=28; Name=DB_B; Lsn=456; File=B_02; Size=765}
@{BakId=28; Name=DB_B; Lsn=456; File=B_03; Size=654}
Run Code Online (Sandbox Code Playgroud)
并创建一个新的分组对象,删除冗余的标头信息。
BakId Lsn Name Files
27 123 DB_A {@{File=A_01.bak;Size=777}}
28 456 DB_B {@{File=B_01.bak;Size=888}, @{File=B_02.bak;Size=999}, ...}
Run Code Online (Sandbox Code Playgroud)
我尝试使用组对象,但只能让它适用于一个属性。(所有分组属性都以逗号分隔值的字符串形式进入 Group.Name。)
这是我想到的最好的,但感觉很老套。
$list | Group-Object -Property BakId | % {
$BakId = $_.Name
$Lsn = $_.Group[0].Lsn # <--- is there a better way than this?
$Name = $_.Group[0].Name # <--- Ditto
$Files = $_.Group | Select-Object -Property SequenceNumber, Size
Write-Output (New-Object -TypeName PSObject -Property @{ BakId=$BakId;Files = $Files })
}
Run Code Online (Sandbox Code Playgroud)
有没有更好的办法?
谢谢
您可以通过使用Select-Object具有计算属性的单个调用来简化构造输出对象的方法,并且根据分组属性的顺序,通过集合访问其特定于组的值.Values:
$list | Group-Object -Property BakId, Lsn, Name |
Select-Object @{n='BakId'; e={ $_.Values[0] }},
@{n='Lsn'; e={ $_.Values[1] }},
@{n='Name'; e={ $_.Values[2] }},
@{n='Files'; e={ $_.Group | Select-Object File, Size }}
Run Code Online (Sandbox Code Playgroud)
笔记:
$_.Values[<ndx>]取代$_.Group[0].<name>你的方法;请注意,后者仅对实际分组属性有意义,因为任何其他属性在整个组中都不会是统一的。
从(实例)输出的每个组对象上的集合.Values()按指定的顺序按原样(原始类型)包含该组的共享分组属性值。
相比之下,属性包含所有分组属性值的字符串化组合:包含逗号分隔列表的字符串。
不幸的是,目前缺少此类详细信息。[System.Collections.ArrayList]Group-Object[Microsoft.PowerShell.Commands.GroupInfo].NameGet-Help Group-Object
如果您想避免重复分组属性(例如,准备编写函数包装器;PSv3+):
$props = 'BakId', 'Lsn', 'Name'
$list | Group-Object -Property $props | ForEach-Object {
$propDefs = [ordered] @{}
foreach ($i in 0..($props.Length-1)) { $propDefs.[$props[$i]] = $_.Values[$i] }
$propDefs.Files = $_.Group | Select-Object File, Size
New-Object PSCustomObject -Property $propDefs
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6159 次 |
| 最近记录: |