Urutan elemen dalam Kamus

107

Pertanyaan saya adalah tentang menghitung elemen Kamus

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

Bagaimana urutan elemen-elemen tersebut dihitung? Dapatkah saya memaksakan urutan menurut abjad?

Kapten Komik
sumber

Jawaban:

125

Urutan elemen dalam kamus adalah non-deterministik. Gagasan tentang keteraturan tidak didefinisikan untuk hashtable. Jadi, jangan mengandalkan pencacahan dalam urutan yang sama saat elemen ditambahkan ke kamus. Itu tidak dijamin.

Kutipan dari dok :

Untuk tujuan pencacahan, setiap item dalam kamus diperlakukan sebagai KeyValuePair<TKey, TValue>struktur yang mewakili nilai dan kuncinya. Urutan pengembalian barang tidak ditentukan.

Darin Dimitrov
sumber
1
Tapi ada OrderedDictionary .
Peter Mortensen
28

Jika Anda ingin elemen diurutkan, gunakan OrderedDictionary . Sebuah hastable / kamus biasa dipesan hanya dalam beberapa arti dari tata letak penyimpanan.

Mitch Wheat
sumber
10
OrderedDictionary dalam banyak kasus salah. Itu tidak Diurutkan berdasarkan kunci atau nilai, tetapi oleh Indeks internal. SortedDictionary adalah yang dipesan dengan cara yang dapat dimanipulasi pengguna (kunci default)
Offler
3
Pertanyaannya adalah menanyakan tentang pengurutan menurut abjad (dengan asumsi penanya berbicara tentang kuncinya). Kamus berurutan, jika saya memahami dokumentasinya dengan benar, akan memuntahkan elemen sesuai urutan penyisipannya, yaitu bukan menurut abjad, tetapi menggunakan indeks internal. SortedDictionary mungkin paling cocok untuk pertanyaan pengguna.
mattpm
28

Anda selalu bisa menggunakannya SortedDictionaryuntuk itu. Perhatikan bahwa kamus diurutkan berdasarkan Key, secara default, kecuali pembanding telah ditentukan.

Saya skeptis tentang penggunaan OrderedDictionaryuntuk apa yang Anda inginkan karena dokumentasi mengatakan bahwa:

Elemen dari OrderedDictionary tidak diurutkan berdasarkan kunci, tidak seperti elemen kelas SortedDictionary.

Adriano Carneiro
sumber
Penting untuk dicatat bahwa SortedDictionary<K,V>diimplementasikan sebagai Pohon Pencarian Biner, yang memberikan operasi waktu dan ruang kompleksitas yang berbeda dibandingkan dengan berbasis hashtable Dictionary<K,V>. Jika pengguna memerlukan O(1)struktur hashtable sisipkan / hapus dan juga ingin mengulang elemen dalam urutan kunci maka mereka harus melakukannya dict.Keys.OrderBy( k => k ).Select( k => dict[k] )(dengan biaya O(n)ruang dan O( n log n )waktu) untuk OrderBy()(yang perlu menyangga seluruh koleksi kunci dalam daftar internal ).
Dai
12

Item akan dikembalikan dalam urutan yang kebetulan disimpan secara fisik di kamus, yang bergantung pada kode hash dan urutan item ditambahkan. Dengan demikian, urutan akan tampak acak, dan saat penerapan berubah, Anda tidak boleh bergantung pada urutan yang tetap sama.

Anda dapat memesan item saat menghitungnya:

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

Dalam framework 2.0, pertama-tama Anda harus memasukkan item ke dalam daftar untuk mengurutkannya:

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) {
  ...
}
Guffa
sumber
11

Untuk OrderedDictionary:

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

Item dikembalikan sesuai urutan penambahannya.

Rumah di luar kota
sumber
5

Array asosiatif (alias, tabel hash) tidak berurutan, yang berarti bahwa elemen dapat diurutkan dengan cara apa pun yang bisa dibayangkan.

NAMUN, Anda dapat mengambil kunci array (hanya kunci), mengurutkan sesuai abjad (melalui fungsi sortir) dan kemudian mengerjakannya.

Saya tidak dapat memberi Anda sampel C # karena saya tidak tahu bahasanya, tetapi ini seharusnya cukup bagi Anda untuk melanjutkan sendiri.

Tim Čas
sumber