Hi all,
So I have a very large data set that takes some text input and turns it into a PSCustomObject. I then want to add that object to my list of all objects unless it exists already, then I just want to add one member of the new object to a member of an existing object in the list. So as an example, here is my data structure and execution:
$allObjs = New-Object System.Collections.ArrayList $obj = [pscustomobject]@{ Name = "" Gender = "" Size = "" Value = 0 } #... #Do some stuff, populate each key at different times.... $obj.Name = "Frankie" #... $obj.Size = "L" $obj.Value = 14993 #... $obj.Gender = "Male" $allObjs.Add($obj)
Now this works as expected. Only problem is that it can create duplicates. Name, Size, and Gender the keys that become the fingerprint for a specific object. The variance is the Value attribute. So let’s say “Frankie” is in multiple books having different “Values” assigned to him. I want to add those up across all books containing “Frankie”.
I came up with this function that merges any duplicates that somehow got added into the list and merges their “Value” keys with some basic and primitive error checking.
FUNCTION Add_Obj { PARAM ( [pscustomobject]$obj ) IF ($obj -eq $null -Or $obj -isnot [pscustomobject]) {return} $tempObj = $allObjs | Where-Object {($_.Name -eq $obj.Name) -and ($_.Gender -eq $obj.Gender) -and ($_.Size -eq $obj.Size)} IF ($tempObj -eq $null) { [void]$allObjs.Add($Obj)} ELSE { IF ($tempObj -is [array]) { $newObj = [pscustomobject]@{Name="";Gender="";Size="";Value=0} FOREACH ($dup in $tempObj) { $allObjs.Remove($dup) $newObj.Name = $dup.Name $newObj.Gender = $dup.Gender $newObj.Size = $dup.Size $newObj.Value += $dup.Value } [void]$allObjs.Add($newObj) } ELSEIF ($tempObj -is [pscustomobject]) { $tempObj.Value += $obj.Value } } } ##### Output: PS C:\Users\Steve> $allObjs = New-Object System.Collections.ArrayList PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "Frankie";Gender = "Male";Size = "L";Value = 1337 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "Dude";Gender = "Male";Size = "L";Value = 100000 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "Frank";Gender = "Male";Size = "S";Value = 5002365 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "Jane";Gender = "Female";Size = "S";Value = 69696969 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "June";Gender = "Female";Size = "L";Value = 42 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "June";Gender = "Female";Size = "L";Value = 420 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "June";Gender = "Female";Size = "L";Value = 4200 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "June";Gender = "Female";Size = "L";Value = 42000 }) PS C:\Users\Steve> Add_Obj -obj ([pscustomobject]@{Name = "June";Gender = "Female";Size = "L";Value = 420000 }) PS C:\Users\Steve> PS C:\Users\Steve> $allObjs Name Gender Size Value ---- ------ ---- ----- Frankie Male L 1337 Dude Male L 100000 Frank Male S 5002365 Jane Female S 69696969 June Female L 466662
Now I can spam this function all day long and not end up with multiple “Frankie”'s who are Size L and Gender Male. It just seems like there has to be a better way of doing this. The code above seems inefficient. This is only an example mind you. My actual data set has 2 keys that are my fingerprint and 9 keys that will either be added to or subtracted from depending on the situation. I’m parsing a few thousand lines of text because some vendor who shall remain nameless can’t expose these variables via JSON/RESTFUL API… anyways, I need this to be fast.
Thank you for your time,
Steve