C#频率分布关联容器初始化-避免哈希两次

时间:2019-01-24 07:58:56

标签: c# dictionary hash counter

一些背景。有一个class Card,它有一个名为enum的{​​{1}}和一个类型为RANK的成员Rank。目的是获取一个RANK,并产生一个像对象的字典,该字典像IEnumerable<Card>Key组成,RANK d则由所争论的序列中的这种等级的数目决定。 例如。在扑克的情况下,具有四张A的五张牌序列将产生一个阶变Value字典。下面是我所拥有的功能。

{(ACE,4),(someOtherRank,1)}

我的问题是此函数被称为无数次,尽管字典的大小是针对该域的最佳大小,但我无法想到一种避免两次哈希以构建对象的方法(一次在TryGet中执行,一次应用该值,无论是从static IReadOnlyDictionary<Card.RANK, int> GetRankDistribution(IEnumerable<Card> hand) { var distribution = new Dictionary<Card.RANK, int>(13); foreach (Card.RANK rank in hand.Select(card => card.Rank)) { distribution.TryGetValue(rank, out var valueBuffer); distribution[rank] = valueBuffer + 1; } return distribution; } 还是从功能int()开始递增。

在C ++中,我可以在循环主体中使用++。如果不存在++dictionary[rank];,则将其插入,并使用默认的Key原位构造,并返回其引用(precrement™的最终操作数)。

在Python中,我只能Value,并且谁知道会发生什么,但这在语法上至少是优雅的。

在给定最原始的值类型的情况下,C#中有什么方法可以有效地实现C ++映射运算符[](好坏)?

如果答案中涉及继承和重构,那么我个人认为我认为它不是“有效的”。

1 个答案:

答案 0 :(得分:1)

确定:

var dictionary = hand.GroupBy(x => x.Rank).ToDictionary(x => x.Key, x => x.Count());