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

如何按值元素对C# Dictionary<string, List<int>>进行分组并生成目标字典?

实现Dictionary按值元素反向分组的最优方案

咱们先明确下需求场景:现有一个键为字符串、值为整数列表的字典,现在要反向按整数元素分组——把所有包含某个整数的原字典键收集成列表,作为新字典的键;而属于同一组原键的所有整数,收集成列表作为新字典的值。

原始字典定义:

var dict = new Dictionary<string, List<int>> { 
    ["a"] = new List<int>{1,2}, 
    ["b"] = new List<int>{2,3}, 
    ["c"] = new List<int>{4,5} 
};

期望得到的结果:

var result = new Dictionary<List<string>, List<int>> { 
    [new List<string> { "a"}] = new List<int> { 1 }, 
    [new List<string> { "b"}] = new List<int> { 3 }, 
    [new List<string> { "a", "b"}] = new List<int> { 2 }, 
    [new List<string> { "c"}] = new List<int> { 4, 5 } 
};

最优实现方案

这里推荐用LINQ + 自定义列表相等比较器的组合,既简洁高效,又能解决列表作为字典键的相等比较问题:

第一步:定义列表内容相等比较器

因为List<string>作为字典键时,默认是引用比较(只有同一实例才会被视为相同键),所以需要自定义一个基于内容比较的相等器:

public class ListEqualityComparer<T> : IEqualityComparer<List<T>> where T : IEquatable<T>
{
    public bool Equals(List<T> x, List<T> y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;
        if (x.Count != y.Count) return false;
        // 逐元素比较内容
        for (int i = 0; i < x.Count; i++)
        {
            if (!x[i].Equals(y[i])) return false;
        }
        return true;
    }

    public int GetHashCode(List<T> obj)
    {
        if (obj == null) return 0;
        // 基于元素内容生成哈希码
        int hash = 17;
        foreach (var item in obj)
        {
            hash = hash * 31 + (item?.GetHashCode() ?? 0);
        }
        return hash;
    }
}

第二步:用LINQ实现分组逻辑

var result = dict
    // 1. 展开嵌套集合:把每个整数和它所属的原字典键一一关联
    .SelectMany(kv => kv.Value.Select(num => (Num: num, Key: kv.Key)))
    // 2. 按整数分组,拿到每个整数对应的所有原键(排序保证键集合顺序一致)
    .GroupBy(item => item.Num, item => item.Key)
    .Select(g => (Keys: g.OrderBy(k => k).ToList(), Num: g.Key))
    // 3. 按键集合分组,把属于同一组原键的整数归到一起
    .GroupBy(item => item.Keys, item => item.Num, new ListEqualityComparer<string>())
    // 4. 转换为目标字典,传入比较器保证键的内容比较
    .ToDictionary(g => g.Key, g => g.ToList(), new ListEqualityComparer<string>());

逻辑解释

  • SelectMany:把原字典的嵌套列表“扁平化”,让每个整数都和它的原键形成独立条目,这是处理嵌套集合的核心操作。
  • 第一次GroupBy:先按整数分组,得到每个整数对应的所有原键;这里对原键排序很关键,能避免因为原键顺序不同(比如["b","a"]和["a","b"])被当成不同键集合的问题。
  • 第二次GroupBy:把拥有相同原键集合的整数归为一组,这里必须传入自定义比较器,否则字典无法识别内容相同的不同列表实例。
  • ToDictionary:最终转换为目标字典,同样需要传入比较器确保键的比较逻辑正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:57:53