Adding together duplicate values in an array

Tagged: 

This topic contains 7 replies, has 4 voices, and was last updated by Profile photo of L-Bo L-Bo 4 months ago.

Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #40790
    Profile photo of L-Bo
    L-Bo
    Participant

    Hello Powershell.org. I have been searching google all day for an answer to this and I am just not getting what I need so hopefully somebody here can offer some assistance. The short explanation is that I have 2 arrays that each contain some duplicate info. See below

    $ObjColl
    
    Name       TotalUsers TotalInbox
    ----                ----------        ----------
    IT                         3               3
    Accounting        4               2
    Marketing          2               1
    

    And the second one....

    $ObjColl1
    
    Name       TotalUsers TotalInbox
    ----               ----------          ----------
    Accounting       2                1         
    Marketing         2                1         
    

    So when I add them together:

    $Final += $Objcoll
    $Final += $Objcoll1
    

    I get the following output:

    $Final
    
    Name       TotalUsers TotalInbox
    ----                 ----------        ----------
    IT                          3                3
    Accounting         4                2
    Marketing           2                1
    Accounting         2                1
    Marketing           2                1
    

    What I actually want to do is aggregate the totals rather than doing a literal "combining" of the arrays. How can this be accomplished? Example of desired output below:

    $Final
    
    Name       TotalUsers TotalInbox
    ----                  ----------       ----------
    IT                          3                3
    Accounting         6                3
    Marketing           4                2
    

    Thanks in advance for any assistance!

    #40801
    Profile photo of konfigurationking
    konfigurationking
    Participant

    Try this and see if it works:

    #40810
    Profile photo of Flynn Bundy
    Flynn Bundy
    Participant

    Hi L-Bo,

    By the looks of it you have two Objects stored in two different variables. Your Objects have three properties – Name, TotalUsers and TotalInbox.

    Here is an example that you can take and re-work to suit your needs.

    $x = [PscustomObject]@{
    Numbers = 1
    AnotherNumber = 5
    }
    
    $y = [PsCustomObject]@{
    Numbers = 2
    AnotherNumber = 5
    }
    
    $b = [PsCustomObject]@{
    Numbers = ($x.Numbers + $y.numbers)
    AnotherNumber = ($x.AnotherNumber + $y.AnotherNumber)
    
    }
    
    

    This is a very basic example of how you can create your own object with information from the properties of other objects. Let us know how you go with your scripting!

    #40854
    Profile photo of L-Bo
    L-Bo
    Participant

    Thank you both for the prompt response. I tried the suggestion that KonfigurationKing suggested though I didn't think it would work for me. I ended up changing the pscustomobject I had into a hashtable object, but still with duplicate values. I have yet to try Flynn's suggestion, but in reading it I can see the concept and I think that is what I am looking for. I will let you know how it works for me, the help is much appreciated!

    #41075
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Not sure how you got two posts in here. Look at the other for a dynamic example.

    #41085
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Because I'm bored.

    
    $one = 'IT','Accounting','Marketing' | % {
    
    [pscustomobject]@{
    
    name = $_
    totalusers = (1..9) |Get-Random
    totalinbox = (1..9) |Get-Random
    
    }
    
    }
    
    
    $two = 'IT','Accounting','Marketing' | % {
    
    [pscustomobject]@{
    
    name = $_
    totalusers = (1..9) |Get-Random
    totalinbox = (1..9) |Get-Random
    
    
    }
    
    }
    
    
    $points = $one + $two | group name | %{
    
    $n = $_.name
    $group = $total | ? {$_.name -eq $n}
    
    [pscustomobject]@{
    
    name = $n
    totalusers = ($group.totalusers | Measure-Object -Sum).sum
    totalinbox = ($group.totalinbox | Measure-Object -Sum).sum
    
    
    }
    
    }
    
    
    [void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms.DataVisualization")
    $chart1 = New-object System.Windows.Forms.DataVisualization.Charting.Chart
    $chart1.Width = 800
    $chart1.Height = 150
    $chart1.BackColor = [System.Drawing.Color]::White
    [void]$chart1.Titles.Add("Total Users")
    $chart1.Titles[0].Font = "segoeuilight,10pt"
    $chart1.Titles[0].Alignment = "topLeft"
    $chartarea = New-Object System.Windows.Forms.DataVisualization.Charting.ChartArea
    $chartarea.Name = "ChartArea1"
    $chart1.ChartAreas.Add($chartarea)
    [void]$chart1.Series.Add("data1")
    $chart1.Series["data1"].ChartType = [System.Windows.Forms.DataVisualization.Charting.SeriesChartType]::Bar
    $chart1.Series["data1"].CustomProperties = 'BarLabelStyle=Outside,DrawingStyle=Emboss'
    $chart1.Series["data1"].Palette = 'BrightPastel'
    $x = $points.name
    $y = $points.totalusers
    $chart1.Series["data1"].Points.DataBindXY([string[]]$x, [int[]]$y)
    $chart1.ChartAreas.AxisX.MajorGrid.Enabled = $false
    $chart1.ChartAreas.AxisY.MajorGrid.Enabled = $false
    $chart1.SaveImage("chart.png", "png")
    
    chart.png
    
    
    #41087
    Profile photo of Dan Potter
    Dan Potter
    Participant

    Flynn,

    You have to account for duplicates. Array could contain one or more of the same therefore you group first to get the unique values and then do the math.

    #41145
    Profile photo of L-Bo
    L-Bo
    Participant

    Thank you all for the prompt replies and the good ideas to try out! Dan Potter had the suggestion that worked the best for me. The Chart.png was a really fancy touch! You were missing the "start-process" cmdlet in front of it to make it auto launch, but I really like the presentation! I have pasted my full working code below in case anyone is interested, or finds this helpful. I am also open to constructive criticism, if anyone sees any better, more efficient ways to achieve the same results I am welcome to them!

    $ADIV = Get-ADOrganizationalUnit -SearchBase 'OU=Adiv,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter *
    $BDIV = Get-ADOrganizationalUnit -SearchBase 'OU=Bdiv,OU=HQ,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter * 
    $CDIV = Get-ADOrganizationalUnit -SearchBase 'OU=Cdiv,OU=New,OU=Units,DC=acmecorp,DC=bdiv,DC=com' -Filter *
    
    [array]$Objcoll = @()
    [array]$Objcoll1 = @()
    [array]$Objcoll2 = @()
    [array]$Final = @()
    
    ForEach($I in $ADIV.distinguishedname)
    {
        $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department
    
        $Props = [ordered]@{
        Unit = (Get-ADOrganizationalUnit -Identity $I).name
        UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
        InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
        }
    
        $Obj = New-Object -TypeName PSObject -Property $Props
    
        $Objcoll += $Obj
    }
    
    ForEach($I in $BDIV.distinguishedname)
    {
        $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department
    
        $Props = [ordered]@{
        Unit = (Get-ADOrganizationalUnit -Identity $I).name
        UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
        InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
        }
    
        $Obj1 = New-Object -TypeName PSObject -Property $Props
    
        $Objcoll1 += $Obj1
    }
    
    ForEach($I in $CDIV.distinguishedname)
    {
        $Data = Get-ADUser -Filter * -SearchBase $I -Properties mailnickname,department
    
        $Props = [ordered]@{
        Unit = (Get-ADOrganizationalUnit -Identity $I).name
        UsersTotal = ($Data | ? {$_.Department -eq 'BDIV'}).count
        InboxesTotal = ($Data | ? {$_.Department -eq 'BDIV' -and $_.MailNickName -ne $null}).count
        }
    
        $Obj2 = New-Object -TypeName PSObject -Property $Props
    
        $Objcoll2 += $Obj2
    }
    
    $Objcoll += $Objcoll1
    $Objcoll += $Objcoll2
    
    ($Objcoll | sort Unit) | %{
    
    $N = $_.Unit
    $Group = $Objcoll | ? {$_.Unit -eq $N}
    
    $FObj = [pscustomobject]@{
    Unit = $N
    UsersTotal = ($Group.UsersTotal | Measure-Object -Sum).sum
    InboxesTotal = ($Group.InboxesTotal | Measure-Object -Sum).sum
    }
    
    if($Final.Unit -match $Fobj.Unit)
    {"Unit already exists in Final report"}
    Else
    {$Final += $FObj}
    
    }
    $Final
    
Viewing 8 posts - 1 through 8 (of 8 total)

You must be logged in to reply to this topic.