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

C#中两种生成逆字典的实现代码是否输出相同结果?

两段逆字典生成代码是否等价?

现有一个姓名映射至电话号码的字典(存在重复号码的情况),需要生成将号码映射至姓名列表的逆字典。分别实现了以下两个版本的ToInverseDictionary方法,询问这两段代码是否会产生相同的结果:

版本1:foreach循环实现

private static IDictionary<T, IList<U>> ToInverseDictionary<T, U>(IDictionary<U, T> dictionary)
{
    var inverseDictionary = new Dictionary<T, IList<U>>();

    foreach (var objU in dictionary.Keys)
    {
        var objT = dictionary[objU];

        if (inverseDictionary.TryGetValue(objT, out var objsUExisting))
        {
            objsUExisting.Add(objU);
        }
        else
        {
            var objsU = new List<U>();
            objsU.Add(objU);
            inverseDictionary[objT] = objsU;
        }
    }

    return inverseDictionary;
}

版本2:LINQ实现

private static IDictionary<T, IList<U>> ToInverseDictionary<T, U>(IDictionary<U, T> dictionary)
{
    return dictionary.GroupBy(kvp => kvp.Value).ToDictionary(grouping => grouping.Key, grouping => grouping.Select(g => g.Key).ToList());
}

结论

是的,这两段代码会产生完全相同的结果,逻辑完全等价。拆解LINQ版本的执行逻辑就能明白:

  1. GroupBy(kvp => kvp.Value):把原字典的所有键值对(姓名-号码)按照Value(即电话号码)分组,每个分组的Key是电话号码,分组内包含所有原字典中映射到该号码的键值对。
  2. ToDictionary(...):将分组转换为目标逆字典:
    • 字典的Key直接取用分组的Key(电话号码);
    • 字典的Value是从分组的每个键值对里提取Key(姓名),再转成List<U>——这和foreach循环里逐个把姓名添加到对应号码列表的逻辑完全一致。

额外细节:

  • 两者生成的姓名列表顺序一致:.NET中Dictionary.Keys的遍历顺序,加上GroupBy保持原序列顺序的特性,会让姓名列表里的元素顺序和原字典中键的顺序完全相同;
  • 对重复号码的处理逻辑毫无差别:所有映射到同一号码的姓名都会被收集到同一个列表里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 03:55:07