Порядок елементів у словнику


107

Моє запитання щодо перерахування елементів словника

// Dictionary definition
private Dictionary<string, string> _Dictionary = new Dictionary<string, string>();

// add values using add

_Dictionary.Add("orange", "1");
_Dictionary.Add("apple", "4");
_Dictionary.Add("cucumber", "6");

// add values using []

_Dictionary["banana"] = 7;
_Dictionary["pineapple"] = 7;

// Now lets see how elements are returned by IEnumerator
foreach (KeyValuePair<string, string> kvp in _Dictionary)
{
  Trace.Write(String.Format("{0}={1}", kvp.Key, kvp.Value));
}

У якому порядку будуть перераховані елементи? Чи можу я змусити наказ бути алфавітним?


Відповіді:


125

Порядок елементів у словнику є недетермінованим. Поняття порядку просто не визначається для хештелів. Тому не покладайтеся на перерахування в тому ж порядку, що елементи були додані до словника. Це не гарантується.

Цитата від doc :

Для перерахування кожен елемент у словнику трактується як KeyValuePair<TKey, TValue>структура, що представляє значення та його ключ. Порядок повернення елементів не визначений.



28

Якщо ви хочете, щоб елементи впорядковані, використовуйте OrdersDictionary . Звичайний hastable / словник впорядкований лише в певному сенсі макета зберігання.


10
Упорядкований словник в більшості випадків помиляється. Це не впорядковано за ключем чи значенням, а за внутрішнім індексом. SortedDictionary - це той, який замовлений таким чином, щоб користувач міг маніпулювати (клавіша за замовчуванням)
Пропозиція

2
Питання - це питання про замовлення в алфавітному порядку (якщо припустити, що запитуючий говорить про ключ). Упорядкований словник, якщо я правильно розумію документацію, випльовуватиме елементи в тому порядку, в який вони вставлені, тобто не в алфавітному порядку, а з використанням внутрішнього покажчика. SortedDictionary, мабуть, найкраще підходить для запитання користувача.
mattpm

28

Ви завжди можете використовувати SortedDictionaryдля цього. Зауважте, що словник за замовчуванням впорядкований Key, якщо не вказано порівняльник.

Я скептично ставлюсь до використання того, OrderedDictionaryщо ви хочете, оскільки документація говорить:

Елементи OrdersDictionary не сортуються за ключем, на відміну від елементів класу SortedDictionary.


Важливо зауважити, що SortedDictionary<K,V>реалізовано як дерево бінарного пошуку, яке надає своїм операціям різну складність у часі та просторі порівняно з основою хештелю Dictionary<K,V>. Якщо користувачам потрібна структура O(1)вставки / видалення хешбелів, а також вони хочуть переглядати елементи впорядкованому ключі, вони повинні dict.Keys.OrderBy( k => k ).Select( k => dict[k] )замість цього (за рахунок O(n)місця та O( n log n )часу) для OrderBy()(що потрібно буде буферизувати всю колекцію ключів у внутрішньому списку ).
Дай

12

Елементи будуть повернуті в тому порядку, який вони фізично зберігаються у словнику, що залежить від хеш-коду та порядку, коли елементи були додані. Таким чином, порядок здасться випадковим, і коли зміни змінюються, ви ніколи не повинні залежати від того, щоб замовлення залишалося таким же.

Ви можете замовити товари при їх перерахуванні:

foreach (KeyValuePair<string, string> kvp in _Dictionary.OrderBy(k => k.Value)) {
  ...
}

У рамках 2.0 вам слід спершу поставити елементи в список, щоб сортувати їх:

List<KeyValuePair<string, string>> items = new List<KeyValuePair<string, string>>(_Dictionary);
items.Sort(delegate(KeyValuePair<string, string> x, KeyValuePair<string, string> y) { return x.Value.CompareTo(y.Value); });
foreach (KeyValuePair<string,string> kvp in items) {
  ...
}

11

Для впорядкованого словника:

 var _OrderedDictionary = new System.Collections.Specialized.OrderedDictionary();

_OrderedDictionary.Add("testKey1", "testValue1");
_OrderedDictionary.Add("testKey2", "testValue2");
_OrderedDictionary.Add("testKey3", "testValue3");

var k = _OrderedDictionary.Keys.GetEnumerator();
var v = _OrderedDictionary.Values.GetEnumerator();

while (k.MoveNext() && v.MoveNext()) {
    var key = k.Current; var value = v.Current;
}

Елементи повертаються в тому порядку, як вони додані.


5

Асоціативні масиви (також, хеш-таблиці) не упорядковані, це означає, що елементи можна упорядкувати будь-яким способом, який можна уявити.

ЗАРАЗ, ви можете отримати ключі масиву (тільки клавіші), замовити це в алфавітному порядку (за допомогою функції сортування), а потім працювати над цим.

Я не можу надати вам зразок C #, оскільки я не знаю мови, але цього має бути достатньо, щоб ви продовжили себе.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.