You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从CardValue枚举创建Dictionary<CardValue, int>统计牌值出现次数

扑克游戏中高效统计CardValue出现次数的实现方案

问题背景

我正在开发一个扑克游戏,拥有一个Card数组,每张牌都具备CardValue枚举类型的属性,需要创建Dictionary<CardValue, int>来统计数组中各CardValue的出现次数。

枚举定义如下:

public enum CardValue
{
    Ace = 1,
    Two = 2,
    Three = 3,
    Four = 4,
    Five = 5,
    Six = 6,
    Seven = 7,
    Eight = 8,
    Nine = 9,
    Ten = 10,
    Jack = 11,
    Queen = 12,
    King = 13
}

目前已手动创建字典,但如果枚举规模扩大,希望找到更高效的自动创建方式,同时必须保留枚举作为字典键以保证可读性(例如用CardValueCount[CardValue.Queen]而非数字索引查询)。当前手动实现代码如下:

public Card[] Cards {get; set;}
private Dictionary <CardValue, int> CardValueCount
{
    get
    {
        var cardValueCount = new Dictionary<CardValue, int>()
        {
            { CardValue.Ace, 0},
            { CardValue.Two, 0},
            { CardValue.Three, 0},
            { CardValue.Four, 0},
            { CardValue.Five, 0},
            { CardValue.Six, 0},
            { CardValue.Seven, 0},
            { CardValue.Eight, 0},
            { CardValue.Nine, 0},
            { CardValue.Ten, 0},
            { CardValue.Jack, 0},
            { CardValue.Queen, 0},
            { CardValue.King, 0}
        };
        if (Cards.Length < 1 || Cards == null)
        {
            return cardValueCount;
        }
        else
        {
            foreach (Card card in Cards)
            {
                cardValueCount[card.Value]++;
            }
            return cardValueCount;
        }
    }
}

解决方案

方法一:自动初始化全枚举字典

通过Enum.GetValues<CardValue>()获取所有枚举值,自动生成初始计数为0的字典,无需手动编写每个键值对:

public Card[] Cards { get; set; }
private Dictionary<CardValue, int> CardValueCount
{
    get
    {
        // 自动生成所有CardValue对应的初始计数0
        var countDict = Enum.GetValues<CardValue>()
                            .ToDictionary(value => value, _ => 0);

        if (Cards == null)
            return countDict;

        foreach (var card in Cards)
        {
            countDict[card.Value]++;
        }

        return countDict;
    }
}

注意:原代码先判断Cards.Length <1会触发空引用异常,需优先判断Cards == null。

方法二:LINQ GroupBy直接生成统计字典

如果允许未出现的枚举值不显示在字典中,可直接用GroupBy一步完成统计:

private Dictionary<CardValue, int> CardValueCount
{
    get
    {
        if (Cards == null || Cards.Length == 0)
        {
            // 若需要空数组时返回全0字典,复用方法一的初始化逻辑
            return Enum.GetValues<CardValue>().ToDictionary(v => v, _ => 0);
        }

        return Cards.GroupBy(card => card.Value)
                    .ToDictionary(group => group.Key, group => group.Count());
    }
}

如果要求未出现的枚举值也保留键并设为0,可将GroupBy结果与全枚举字典合并:

private Dictionary<CardValue, int> CardValueCount
{
    get
    {
        var baseDict = Enum.GetValues<CardValue>().ToDictionary(v => v, _ => 0);
        if (Cards == null || Cards.Length == 0)
            return baseDict;

        var grouped = Cards.GroupBy(c => c.Value)
                           .ToDictionary(g => g.Key, g => g.Count());

        foreach (var kvp in grouped)
        {
            baseDict[kvp.Key] = kvp.Value;
        }

        return baseDict;
    }
}

关键优化点

  1. 修复原代码的空引用风险:必须先判断Cards == null,再访问Length属性
  2. 自动生成字典的方式可避免枚举扩展时手动修改初始化代码,提升可维护性

内容的提问来源于stack exchange,提问作者Adam Cook

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 08:20:49