使用ToDictionary构建排序字典

时间:2013-09-03 01:11:40

标签: c# dictionary hashtable

我不是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>

我期望得到的字典应该像C ++ STL中那样map,它通常被实现为(平衡的)二叉树以维持密钥的排序。但是,生成的字典仍然是哈希表。

sortedDict如何维持订购?哈希表不能保存密钥的顺序。 C#的Generic.Dictionary的实现是否只是典型的哈希表?

3 个答案:

答案 0 :(得分:8)

SortedDictionary会在构造函数中使用现有的Dictionary,因此制作SortedDictionary非常简单。

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

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

答案 1 :(得分:8)

Dictionary维护着两种数据结构:一个扁平数组,按枚举的顺序保存,以及按键检索的哈希表。

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

编辑:如果您想依赖此行为,我建议您查看MSDN文档,看看这是保证还是偶然。

答案 2 :(得分:2)

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));
    }
}
相关问题