Подтвердить что ты не робот

Как вставить элемент в первый индекс в словаре?

Есть ли метод или метод, позволяющий вставить элемент в 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

Любая помощь очень ценится. Спасибо заранее!

4b9b3361

Ответ 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>, но это упорядочено ключом, а не отдельным индексом.

Ответ 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;
}