Сортировка Hashtable по порядку, в котором он был создан

Это похоже на как сохранить порядок элементов в Hashtable, за исключением .Сеть.

есть Hashtable или Dictionary в .NET, который позволяет получить доступ к нему .Index свойство для записи в том порядке, в котором она была добавлена в коллекцию?

6 ответов


A 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.


Если это то, что вам нужно отслеживать эффективно, то вы используете неправильную структуру данных. Вместо этого, вы должны использовать SortedDictionary где ключ помечен индексом, когда он был добавлен (или меткой времени) и пользовательским IComparer, которая сравнивает два ключа на основе индекса (или метки).


есть ли хэш-таблица или словарь в .NET, который позволяет вам получить к нему доступ .Свойство Index для записи в том порядке, в котором она была добавлена в коллекцию?

нет. Вы можете перечислить все элементы в Hastable или словаре, но они не должны быть в каком-либо порядке (скорее всего, это не так)

вам придется либо использовать другую структуру данных (например, SortedDictionary или SortedList), либо использовать отдельный список для хранения порядка, в котором они были добавлены. Вы хотели бы обернуть упорядоченный список и ваш словарь/хэш-таблицу в другой класс, чтобы они синхронизировались.


вы можете использовать отдельный список для хранения элементов в порядке их добавления. Что-то вроде следующего примера:

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...
}

взгляните на класс OrderedDictionary. Вы можете получить к нему доступ не только с помощью клавиш, но и с помощью индекса (позиции).


альтернативой является создание массива структур, поэтому вместо использования

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);

используя этот метод, вы можете добавить дополнительные измерения в список без особых усилий, просто добавьте новый элемент в структуру.

Примечание. Если вам нужно изменить элементы в списке после их добавления, вам придется изменить структуру в класс. См. эту страницу для получения дополнительной информации по этой проблеме: ошибка изменения значения структуры в списке