使用Powershell,如何计算数组中每个元素的出现次数?

19

如果我有一个数组:

1 1 1 2 2 3 4 4 4 4 5 5

如何使用Powershell告诉我该数组中每个元素的数量?

更清楚地说,我应该为每个数组元素单独计数:

元素:计数

1:3

2:2

3:1

4:4

5:2

3个回答

37
你可以使用 Group-Object 命令:
PS> 1,1,1,2,2,3,4,4,4,4,5,5 | group

Count Name                      Group
----- ----                      -----
    3 1                         {1, 1, 1}
    2 2                         {2, 2}
    1 3                         {3}
    4 4                         {4, 4, 4, 4}
    2 5                         {5, 5}

如果您想要一个存储项目及其计数的哈希表,只需在其后添加一些 ForEach-Object 即可:

$array | group | % { $h = @{} } { $h[$_.Name] = $_.Count } { $h }

谢谢。有什么优雅的方法可以推导出原始数组的“mode”(最常出现的值)吗?也就是说,给定OP的数组1 1 1 2 2 3 4 4 4 4 5 5,我需要返回4 - Ifedi Okonkwo
1
@IfediOkonkwo: 1,1,1,2,2,3,4,4,4,4,5,5 | group -NoElement | sort Count | select -last 1 -expandProperty Name。虽然有点长,但管道中的每个部分都只做一件事,并且组合得很好。另一个选项是将获取值和选择最后一个值分开处理,使用 ... | group -NoElement | sort Count | % Name | select -last 1 - Joey
@Joey:非常感谢。在看到你的回复之前,我已经拼凑出了一些东西,虽然比你的更加笨重:$hash = $Array | group | % { $h = @{} } { $h[$_.Name] = $_.Count } { $h }; $mode = $hash.GetEnumerator() | Sort-Object -Property Value -Descending | Select-Object -First 1 - Ifedi Okonkwo
@mklement0:我完全同意你的观点。但是,有时候懒惰会占上风,这很人性化。希望谷歌仍然可以将搜索者引导到这个帖子中 ;) - Ifedi Okonkwo
1
@IfediOkonkwo:或者,我们可以做正确的事情。请注意,您的解决方案无法处理出现最频繁的“多个”值的情况。 - mklement0
哇!你那个详尽的自问自答真是让我汗颜啊!干得好,问题和回答都加一分。 - Ifedi Okonkwo

7
Joey的有用回答提供了关键指针:使用 Group-Object cmdlet 按相等性对输入对象进行分组。
(要按它们的一个或多个属性值进行分组,可以使用 -Property)。

Group-Object 输出代表相等输入对象的[Microsoft.PowerShell.Commands.GroupInfo] 对象,其值得注意的属性是:

  • .Values ... 定义该组的值,作为 [System.Collections.ArrayList] 实例(在这种情况下,由于使用输入对象作为整体来形成组,因此只有1个元素)。

  • .Count ... 该组中对象的计数。

如果在这种情况下不需要将每个组的个体成员收集为一部分,则可以使用-NoElement来提高效率。
您可以自由地进一步处理组对象,以满足您问题中规定的特定输出格式,您可以使用Select-Object计算属性
把它们全部结合起来:
PS> 1, 1, 1, 2, 2, 3, 4, 4, 4, 4, 5, 5 | Group-Object -NoElement |
      Select-Object @{ n='Element:Count'; e={ '{0}:{1}' -f $_.Values[0], $_.Count } }

Element:Count
-------------
1:3
2:2
3:1
4:4
5:2

7
您可以根据需要调整输出并格式化它:
PS> $ht= 1,1,1,2,2,3,4,4,4,4,5,5 | Group-Object -AsHashTable -AsString
PS> $ht

Name                           Value
----                           -----
2                              {2, 2}
4                              {4, 4, 4, 4}
5                              {5, 5}
1                              {1, 1, 1}
3                              {3}


PS> $ht['1']
1
1
1

3
他们想要计数,因此-AsHashTable帮助不大。 - Joey
2
$ht['#'].count, in System.Collections.Hashtable it contains a method called count - Riley Carney

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接