Home > OS >  Merge Two Groups in a Group Collection
Merge Two Groups in a Group Collection

Time:05-12

I Need to Group two Grouped Object into one Group, see example:

Name    Count Group                                             
----    ----- -----                                             
4771343    89 {@{Id=4be956d4-c46e-4456-8666-7a642cc1e8f8;[...]}}
4771342    44 {@{Id=4be956d4-c46e-4456-8666-7a642cc1e8f8;[...]}}

I want to merge this Two Group into One Group with the values in both, like this:

Name    Count Group                                             
----    ----- -----                                             
4771343    133 {@{Id=4be956d4-c46e-4456-8666-7a642cc1e8f8;[...]}}

What I tried is:

a. Creating a custom GroupInfo Object, which have no constructor and can't created manually

b. Modify the Group manually is impossible as it's read-only

c. So, I Manually update the object like this:

$RelevantGroups = $Groups | ? Name -Match '4771342|4771343'
$TempGroup = $Groups[0]
$field = $TempGroup.GetType().GetField('name','static,nonpublic,instance')
$field.SetValue($TempGroup,"4771343")

$Collection = [System.Collections.ObjectModel.Collection[psobject]]::new()    
$Collection.Add($RelevantGroups.Group)

$field = $TempGroup.GetType().GetField('group','static,nonpublic,instance')
$field.SetValue($TempGroup,$Collection)

$field = $TempGroup.GetType().GetField('count','static,nonpublic,instance')
$field.SetValue($TempGroup,133)

But because it's a Reference Type it's update the original object, I can solve it with new object but it feels a mess...

Do you have any idea how to achieve this??

CodePudding user response:

You just need the grouping key to evaluate to the same number for both groups of input objects, which you can do with a property expression like this:

$Groups = $Filtered | Group-Object {
  if($_.MpnId -eq 4771342){
    4771343
  }
  else {
    $_.MpnId
  }
}

If you have multiple mappings like this, arrange them in a dictionary and use that to resolve the grouping key:

$mapping = @{
    '4771342' = '4771343'
    '1234567' = '2345678'
}

$Groups = $Filtered | Group-Object {
  $idAsString = "$($_.MpnId)"
  if($mappings.ContainsKey($idAsString)){
    $mappings[$idAsString]
  }
  else {
    $idAsString
  }
}

The reason I'm "stringifying" the ID value is to avoid type confusion in case MpnId contains integer values of a different type than [int] (in which case the ContainsKey() call might fail for the same two values)

  • Related