简体   繁体   中英

C# Frequency Distribution Associative Container Initialization-way to avoid hashing twice

Some background. There is a class Card , it has an enum called RANK , and a member Rank of type RANK . The goal is to take an IEnumerable<Card> , and produce a dictionary like object, Key ed by RANK and Value d by the number of such rank in the argued sequence. eg. in the context of Poker, a five card sequence with quad Aces would yield an order-variant {(ACE,4),(someOtherRank,1)} dictionary. Below is the function that I have.

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;
    } 

My problem is this function is called an inordinate amount of times, and allthough the dictionary is optimally sized for the domain, I cannot conceive of a way to avoid hashing twice to build the object(once in the TryGet, and once to apply the value, whether incremented off int() or a functional ++ ).

In C++, I could ++dictionary[rank]; in the loop body. If the Key is absent, it is inserted, with the default Value constructed in situ, and its reference returned(the eventual operand of the precrement™).

In Python, I could just return Counter(hand) , and who knows what happens, but it is at least syntactically elegant.

Is there any way in C#, given the most primitive of value types, to effectively achieve what the C++ map operator[](for better or worse) does?

If inheriting and refactoring are involved in the answer, I personally do not consider it 'effective' as I define it.

当然:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM