2010-11-02 3 views
6

Это похоже на How to keep the order of elements in hashtable, за исключением .NET.Сортировка Hashtable по заказу, в котором он был создан

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

ответ

5

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.

+0

Это замечательно. Альтернатива Hashtable и Dictionary, которая проста. Кроме того, примечание о порядке сортировки словаря по умолчанию очень полезно. –

+0

Не забудьте добавить: using System.Collections.Specialized; –

5

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

3

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

No. Вы можете enumarate по всем пунктам в Hastable или словаря, но они не gaurenteed быть в какой-либо заказ (скорее всего, они не являются)

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

3

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

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

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

Обратите внимание: если вам нужно изменить элементы в списке после их добавления, вам придется изменить структуру в класс. См. Эту страницу для получения дополнительной информации по этому вопросу: error changing value of structure in a list

2

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

Смежные вопросы