I'm trying to take an array of PSObjects similar to
@{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}
And create a new grouped object that removes redundant header info.
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}, ...}
I tried using group-object but can only get it to work for one property. (all grouped properties go into Group.Name as aa string of comma separated values.)
This is the best I've come up with, but feels hacky.
$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 })
}
Is there a better way?
Thanks
You can simplify the approach to constructing the output objects by using a single Select-Object
call with calculated properties, and, relying on the order of the grouping properties, access their group-specific values via the .Values
collection:
$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 }}
Note:
$_.Values[<ndx>]
takes the place of $_.Group[0].<name>
in your approach; note that the latter only makes sense for the actual grouping properties, because any others will not be uniform throughout the group.
The .Values
collection ( [System.Collections.ArrayList]
) on each group object output from Group-Object
( [Microsoft.PowerShell.Commands.GroupInfo]
instance) contains that group's shared grouping-property values as-is (original type), in the order specified.
By contrast, property .Name
contains the stringified combination of all grouping-property values: a string containing a comma-separated list.
Unfortunately, such details are currently missing from Get-Help Group-Object
.
If you wanted to avoid having to repeat the grouping properties (eg, in preparation for writing a function wrapper; 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
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.