使用ToDictionary构建排序词典

本文关键字:排序 构建 ToDictionary 使用 | 更新日期: 2023-09-27 18:30:07

我不是C#和LINQ方面的专家。

我有一个Dictionary,我理解它是一个哈希表,也就是说,键是不排序的。

dataBase = new Dictionary<string, Record>()

Record是一个用户定义的类,它为给定的键串保存大量数据。

我发现了一个有趣的例子,它通过LINQ:将这个Dictionary转换为排序的字典

var sortedDict = (from entry in dataBase orderby entry.Key ascending select entry)
.ToDictionary(pair => pair.Key, pair => pair.Value);

此代码工作正常。生成的sortedDict按关键字进行排序。

问题:我发现sortedDict仍然是一个哈希表,类型为:

System.Collections.Generic.Dictionary<string, Record>

我希望得到的字典应该是一种map,就像C++STL中一样,它通常被实现为一个(平衡的)二叉树,以保持密钥的顺序。然而,生成的字典仍然是一个哈希表。

sortedDict如何维护订单?哈希表无法保存密钥的顺序。C#的Generic.Dictionary的实现不是一个典型的哈希表吗?

使用ToDictionary构建排序词典

Dictionary维护两个数据结构:一个平面数组,按插入顺序进行枚举,另一个哈希表,按键检索。

如果在排序集上使用ToDictionary(),则枚举时它将按顺序排列,但不会按顺序维护。枚举时,任何新插入的项都将添加到后面。

编辑:如果你想依赖这种行为,我建议你查看MSDN文档,看看这是有保证的,还是只是偶然的。

SortedDictionary在构造函数中采用现有的Dictionary,因此生成SortedDictionary非常容易。

但如果你愿意,你可以将其作为一种扩展方法,然后你可以使用dataBase.ToSortedDictionary()

public static SortedDictionary<K, V> ToSortedDictionary<K,V>(this Dictionary<K, V> existing)
{
    return new SortedDictionary<K, V>(existing);
}

linq代码看起来是在构建一个排序字典,但排序是由linq完成的,而不是字典本身,而SortedDictionary应该自己维护排序。

要获得已排序的词典,请使用new SortedDictionary<string, Record>(yourNormalDictionary);

如果你想让它更容易访问,那么你可以写一个扩展到ienumerable:

public static class Extensions
{
    public static SortedDictionary<T1, T2> ToSortedDictionary<T1, T2>(this IEnumerable<T2> source, Func<T2, T1> keySelector)
    {
        return new SortedDictionary<T1, T2>(source.ToDictionary(keySelector));
    }
}