按创建顺序排序Hashtable

7

这类似于如何保持Hashtable元素的顺序,但是针对.NET。

在.NET中是否有任何HashtableDictionary允许您访问其.Index属性,以获取按添加到集合中的顺序排列的条目?

6个回答

6

NameValueCollection可以通过索引来检索元素(但您不能请求特定键或元素的索引)。因此,

var coll = new NameValueCollection();
coll.Add("Z", "1");
coll.Add("A", "2");
Console.WriteLine("{0} = {1}", coll.GetKey(0), coll[0]); // prints "Z = 1"

然而,当你多次添加一个键时,它的行为与IDictionary相比有些奇怪:

var coll = new NameValueCollection();
coll.Add("Z", "1");
coll.Add("A", "2");
coll.Add("Z", "3");
Console.WriteLine(coll[0]); // prints "1,3"

行为已有充分记录。
注意:NameValueCollection 没有实现 IDictionary 接口。
顺带一提: Dictionary<K,V> 没有可以使用的索引,但只要您仅添加元素而不删除任何元素,则元素的顺序就是插入顺序。请注意,这是 Microsoft 当前实现的一个细节:文档明确指出顺序是随机的,因此此行为在 .NET Framework 或 Mono 的未来版本中可能会更改。

这很棒。一个简单的Hashtable和Dictionary的替代方案。此外,有关Dictionary默认排序顺序的说明非常有帮助。 - Todd Main
记得添加: using System.Collections.Specialized; - Scott Montgomerie

4

您可以使用单独的列表来按添加顺序存储元素。以下是一个示例:

public class ListedDictionary<TKey, TValue> : IDictionary<TKey, TValue>
{
    List<TValue> _list = new List<TValue>();
    Dictionary<TKey, TValue> _dictionary = new Dictionary<TKey,TValue>();

    public IEnumerable<TValue> ListedValues
    {
        get { return _list; }
    }

    public void Add(TKey key, TValue value)
    {
        _dictionary.Add(key, value);
        _list.Add(value);
    }

    public bool ContainsKey(TKey key)
    {
        return _dictionary.ContainsKey(key);
    }

    public ICollection<TKey> Keys { get { return _dictionary.Keys; } }

    public bool Remove(TKey key)
    {
        _list.Remove(_dictionary[key]);
        return _dictionary.Remove(key);
    }

    // further interface methods...
}

4
如果您需要高效地跟踪某些内容,那么使用错误的数据结构。相反,您应该使用一个SortedDictionary,其中键被标记为添加时的索引(或时间戳),并且使用自定义IComparer根据索引(或时间戳)比较两个键。

4
在.NET中,有任何Hashtable或Dictionary允许您访问其.Index属性以按添加顺序访问集合中的条目吗?
没有。您可以枚举Hashtabe或Dictionary中的所有项,但不能保证这些项以任何形式排序(最有可能不排序)。
您必须使用完全不同的数据结构(例如SortedDictionary或SortedList),或使用单独的列表来存储添加顺序。您需要将有序列表和字典/哈希表包装在另一个类中以使它们同步。

2

看一下OrderedDictionary类。你不仅可以通过键来访问它,还可以通过索引(位置)来访问。


1

另一种方法是创建一个结构数组,这样就不必使用

dictionary.Add{"key1","value1"}

你可以创建一个带有键/值的结构体:

public struct  myStruct{
    private string _sKey;
    public string sKey{
        get { return _sKey; }
        set { _sKey = value; }
    }
    private string _sValue;
    public string sValue {
        get { return _sValue; }
        set { _sValue = value; }
    }
}

// create list here
List<myStruct> myList = new List<myStruct>();

// create an instance of the structure to add to the list
myStruct item = new myStruct();
item.sKey = "key1";
item.sValue = "value1";

// then add the structure to the list
myList.Add(item);

使用这种方法,您可以轻松地向列表添加额外的维度,只需在结构体中添加一个新成员即可。
请注意,如果您需要在添加后修改列表中的项目,则必须将结构体更改为类。有关此问题的更多信息,请参见此页面:更改列表中结构体值时出错

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接