2017-01-05 20 views
1

的陣列加起來的值給出的以下陣列的對象:求的快速,簡潔,清晰和代碼平衡組合以從物體

Email    Domain  Tally 
-----    -----  ----- 
[email protected] domainA.com 4 
[email protected] domainB.com 1 
[email protected] domainC.com 6 
[email protected] domainA.com 1 

我想「組由」域和加起來理貨,我走了。最終結果是這樣的:

Domain  Tally 
------  ----- 
domainA.com 5 
domainB.com 1 
domainC.com 6 

我有一些工作,但我覺得它太複雜了。

$AllTheAddresses = Get-AllTheAddresses 

$DomainTally = @() 
foreach ($Addy in $AllTheAddresses) 
{ 
    if ($DomainTally | Where-Object {$_.RecipientDomain -eq $Addy.RecipientDomain}) 
    { 
     $DomainTally | 
      Where-Object {$_.RecipientDomain -eq $Addy.RecipientDomain} | 
      ForEach-Object {$_.Tally += $Addy.Tally } 
    } 
    else 
    { 
     $props = @{ 
      RecipientDomain = $Addy.RecipientDomain 
      Tally = $Addy.Tally 
     } 
     $DomainTally += New-Object -TypeName PSObject -Property $props 
    } 
} 

回答

3

在我的例子,我創建的地址作爲哈希表,但PowerShell中會讓你通過.Property類似於對象指的是鑰匙。

如果你真的只是通過域進行求和,那麼看起來你不需要比HashTable更復雜的任何東西來創建你的運行總數。

基本總和:

$Tally = @{} 
$AllTheAddresses | ForEach-Object { 
    $Tally[$_.Domain] += $_.Tally 
} 

採用該試樣數據...

$AllTheAddresses = @( 
    @{ Email = "[email protected]"; Domain = "domainA.com"; Tally = 4 }; 
    @{ Email = "[email protected]"; Domain = "domainB.com"; Tally = 1 }; 
    @{ Email = "[email protected]"; Domain = "domainC.com"; Tally = 6 }; 
    @{ Email = "[email protected]"; Domain = "domainA.com"; Tally = 1 } 
    ) 

,你會得到這樣的輸出:

PS> $tally 
Name       Value                      
----       -----                      
domainC.com     6                       
domainB.com     1                       
domainA.com     5    
+0

謝謝,@ TravisEz13 - 我正要擴展別名,我需要弄清楚標記。 –

+1

快速,簡潔,清晰,贏得 – JamesQMurphy

+0

我想出了'$ Tally.Keys |%{Write-Host $ _; $ Tally。$ _}'。 – Chris76786777

1

這是一個「PowerShellic」版本,請注意數據的管道和流程。 你當然可以把它寫成一個班輪(我在這裏發佈答案之前就是這麼做的)。這個'更好'的部分是使用Group-Object和Measure-Object cmdlet。請注意,沒有條件,因爲示例使用了管道。

$AllTheAddresses | 
Group-Object -Property Domain | 
ForEach-Object { 
    $_ | 
    Tee-Object -Variable Domain | 
    Select-Object -Expand Group | 
    Measure-Object -Sum Tally | 
    Select-Object -Expand Sum | 
    ForEach-Object { 
     New-Object -TypeName PSObject -Property @{ 
      'Domain' = $Domain.Name 
      'Tally' = $_ 
     } 
    } | 
    Select-Object Domain, Tally 
} 

一個更簡潔的版本

$AllTheAddresses | 
Group Domain | 
% { 
    $_ | 
    Tee-Object -Variable Domain | 
    Select -Expand Group | 
    Measure -Sum Tally | 
    Select -Expand Sum | 
    % { 
     New-Object PSObject -Property @{ 
      'Domain' = $Domain.Name 
      'Tally' = $_ 
     } 
    } | 
    Select Domain, Tally 
} 
+0

順便說一句,我批准了修改到增加了很多額外的絨毛:-)以上,但它並使其更具可讀性。如果這是我捏,我可能會使用更多的別名和默認約定參數傳遞。但是,對於非PowerShellers來說,它有點神祕。 –

+0

詳細說明PowerShell的正確編碼。您應該在腳本上運行[PSScriptAnalyzer](https://github.com/PowerShell/PSScriptAnalyzer)。它會推薦這些更改。第一條規則是「[避免別名](https://github.com/PowerShell/PSScriptAnalyzer/blob/development/RuleDocumentation/AvoidAlias.md)」。其次是「[避免使用位置參數](https://github.com/PowerShell/PSScriptAnalyzer/blob/development/RuleDocumentation/AvoidUsingPositionalParameters.md)」。 – TravisEz13

+1

完全同意TravisEz13,這真的取決於這是否會生活在一個腳本或它的OP在命令行上鍵入一次 –

0

Group-Object肯定是要走的路。

在簡潔的興趣:

Get-AllTheAddresses |Group-Object Domain |Select-Object @{N='Domain';E={$_.Name}},@{N='Tally';E={($_.Group.Tally |Measure-Object).Sum}} 
+0

你是否在看到我失蹤的問題?在您的建議的細節中隱藏了很多編程/執行開銷。 –

+0

@MthethewWetmore當然,您的解決方案在速度/開銷方面將超過我的表現,毫無疑問。但是輸出示例OP顯示隱含具有'Domain'和'Tally'屬性的對象集合,您的建議無法生成:-) –

+0

您是否在我的代碼中使用了'.Tally'和''這兩點。來自原始輸入的域屬性?我的示例輸入使用HashTable模擬這些屬性,但解決方案對於具有「Tally」屬性或HashTable具有相同名稱的鍵的對象同樣適用。 –