Как вставить элемент в первый индекс в словаре?
Есть ли метод или метод, позволяющий вставить элемент в
Dictionary<TKey, TValue>
, гарантирующий, что элемент находится в первом индексе этого словаря KeyCollection.
Например:
Dictionary<String, String> dic = foo.GetOutput();
// `dic` is something like:
// {"foo", "baa"},
// {"a", "b"}
Мне нужно что-то вроде:
dic.Add("key", "value", 0);
// where `0` is the index that `key` to be inserted.
foreach(KeyValuePair<String, String> key in dic)
{
Console.WriteLine("{0} = {1}", key.Key, key.Value);
}
Вывод:
key = value
foo = baa
a = b
Любая помощь очень ценится. Спасибо заранее!
Ответы
Ответ 1
Не используя словарь.
Dictionary<TKey, TValue>
реализуется как хэш-таблица. Положение ключей, встроенных в словарь, зависит от хэш-кода, средства, с помощью которого этот хэш-код был уменьшен дальше, чтобы обеспечить индекс во внутренней структуре и порядок вставки полностью зависимым от реализации способом.
Это не единственный способ реализовать словарь. SortedDictionary<TKey, TValue>
использует внутреннюю структуру дерева и поэтому всегда сохраняет ключи в порядке. В этом случае мы все еще не можем вставлять что-то в начале, скорее мы вставляем что-то, и оно помещается в нужное место.
Если упорядочение - это то, о чем вы заботитесь больше всего, тогда вы вообще не хотите puredictionary. Скорее вы хотите либо List<KeyValuePair<TKey, TValue>>
, либо хотите структуру, которая предлагает как функциональность списка, так и словаря, который предоставляется OrderedDictionary
. Это не является общим, но вы можете легко создать общую оболочку вокруг него (не дает преимуществ производительности для внутреннего использования дженериков, но дает возможность использовать тип безопасности).
Ответ 2
Словари неупорядочены; элементы должны быть извлечены ключом, чей хэш указывает на его местоположение значений.
Вам может понадобиться List <KeyValuePair>
, элементы которого могут быть вставлены в определенный индекс.
List<KeyValuePair<string, string>> list = dic.ToList();
list.Insert(0, new KeyValuePair<string, string>("a", "b"));
foreach(KeyValuePair<string, string> pair in list)
Console.WriteLine("{0} = {1}", pair.Key, pair.Value);
Ответ 3
Это невозможно при использовании Dictionary<TKey, TValue>
, поскольку оно перечисляет значения неупорядоченным образом при перечислении. Существует SortedDictionary<TKey, TValue>
, который обеспечивает упорядочение, но он делает это, используя IComparer<TKey>
против значения ключа напрямую. Здесь вы хотите, чтобы ключ был String
и имел упорядочение на основе int
. Это невозможно с любым из этих типов.
Я думаю, вам нужно будет внедрить новый тип с помощью этой очень специфической семантики. Например.
class OrderedMap<TKey, TValue> {
private readonly Dictionary<TKey, TValue> _map = new Dictionary<TKey, TValue>();
private readonly List<TKey> _list = new List<TKey>();
public void Add(TKey key, TValue value) {
if (!_map.ContainsKey(key)) {
_list.Add(key);
}
_map[key] = value;
}
public void Add(TKey key, TValue value, int index) {
if (_map.ContainsKey(key)) {
_list.Remove(key);
}
_map[key] = value;
_list.Insert(index, key);
}
public TValue GetValue(TKey key) {
return _map[key];
}
public IEnumerabe<KeyValuePair<TKey, TValue>> GetItems() {
foreach (var key in _list) {
var value = _map[key];
yield return new KeyValuePair<TKey, TValue>(key, value);
}
}
}
Обратите внимание, что это связано с некоторыми нетривиальными различиями в производительности по сравнению с традиционным Dictionary<TKey, TValue>
. Например, Add
и Remove
работают медленнее.
Ответ 4
Я знаю, что это трехлетний вопрос. Но нашел обходной путь этой проблемы. Это может помочь кому-то
Dictionary<String, String> dic = foo.GetOutput();
dic = (new Dictionary<string, string> {{"key","value"}}).Concat(dic).ToDictionary(k => k.Key, v => v.Value);
Это добавит элемент в начало словаря:)
Ответ 5
Dictionary<TKey, TValue>
по своей сути неупорядочен (или, скорее, порядок непредсказуем и на него нельзя положиться). Если вам нужен какой-то заказ, вам нужно использовать другой тип. Трудно рекомендовать какой-либо конкретный тип, не зная больше о ваших требованиях.
Ответ 6
Класс Dictionary<TKey,TValue>
не содержит элементы упорядоченным образом, поэтому нет "первого" элемента.
Существует SortedDictionary<Tkey,TValue>
(.NET 4.0+), который сортируется по ключу, но опять же, это очень смутная идея от "первого".
Ответ 7
Невозможно упорядочить Dictionary<TKey, TValue>
.
Вместо этого вы можете попробовать SortedDictionary<TKey, TValue>
, но это упорядочено ключом, а не отдельным индексом.
Ответ 8
A Dictionary
- неупорядоченный набор. Вы можете попробовать OrderedDictionary
- http://msdn.microsoft.com/en-us/library/system.collections.specialized.ordereddictionary.aspx - который имеет метод Insert()
, который вам нужен.
Ответ 9
это мое решение, возможно, не лучшее решение, но оно работает. =)
public static ComboBox FillDropDownList(Dictionary<String, String> dictionary, ComboBox dropDown, String selecione)
{
var d = new SortedDictionary<String, String>();
d.Add("0", selecione);
foreach (KeyValuePair<string, string> pair in dictionary)
{
d.Add(pair.Key, pair.Value);
}
dropDown.DataSource = new BindingSource(d, null);
dropDown.DisplayMember = "Value";
dropDown.ValueMember = "Key";
dropDown.SelectedIndex = 0;
return dropDown;
}