Sözlükteki öğelerin sırası


107

Sorum Sözlük öğelerini sıralamakla ilgili

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

Elemanlar hangi sırayla numaralandırılacak? Sırayı alfabetik olmaya zorlayabilir miyim?


Yanıtlar:


125

Bir sözlükteki öğelerin sırası deterministik değildir. Sıra kavramı, hashtable'lar için tanımlanmamıştır. Bu nedenle, öğelerin sözlüğe eklendikleri sırayla numaralandırmaya güvenmeyin. Bu garanti değil.

Dokümandan alıntı :

Numaralandırma amacıyla, sözlükteki her öğe, KeyValuePair<TKey, TValue>bir değeri ve anahtarını temsil eden bir yapı olarak ele alınır . Ürünlerin iade edilme sırası tanımsız.



28

Öğelerin sıralanmasını istiyorsanız, OrderedDictionary kullanın . Sıradan bir hastable / sözlük, yalnızca depolama düzeninin bir anlamıyla sipariş edilir.


10
OrderedDictionary çoğu durumda yanlıştır. Anahtar veya değere göre değil, dahili bir Dizine göre sıralanır. SortedDictionary, kullanıcının işleyebileceği şekilde sıralanandır (varsayılan anahtar)
Offler

3
Soru, alfabetik sıraya göre sıralama hakkında soru sormaktır (soru soran kişinin anahtar hakkında konuştuğunu varsayarsak). Sıralı bir sözlük, dokümantasyonu doğru anlarsam, öğeleri eklendikleri sırayla, yani alfabetik olarak değil, dahili indeksi kullanarak tükürür. SortedDictionary muhtemelen kullanıcının sorusu için en uygun olanıdır.
mattpm

28

Bunun için her zaman kullanabilirsiniz SortedDictionary. Bir karşılaştırıcı belirtilmediği sürece sözlüğün varsayılan olarak Anahtar'a göre sıralandığını unutmayın.

OrderedDictionaryBelgeler şunu söylediğinden, istediğiniz şey için kullanımı konusunda şüpheliyim :

SortedDictionary sınıfının öğelerinden farklı olarak, OrderedDictionary'ın öğeleri anahtara göre sıralanmaz.


Bunun SortedDictionary<K,V>bir İkili Arama Ağacı olarak uygulandığına dikkat etmek önemlidir , bu da işlemlerine hashtable tabanlı ile karşılaştırıldığında farklı zaman ve alan karmaşıklığı verir Dictionary<K,V>. Kullanıcıların bir O(1)hashtable yapısına ihtiyacı varsa ve anahtar sırasına göre öğeleri yinelemek istiyorsa, dict.Keys.OrderBy( k => k ).Select( k => dict[k] )bunun yerine ( O(n)alan ve O( n log n )zaman pahasına ) için OrderBy()(tüm anahtar koleksiyonunu dahili bir listede arabelleğe almaları gerekecektir) ).
Dai

12

Maddeler, karma koduna ve öğelerin eklenme sırasına bağlı olarak, sözlükte fiziksel olarak saklanma sırasına göre iade edilecektir. Böylece sıra rastgele görünecek ve uygulamalar değiştikçe, aynı kalan sıraya asla güvenmemelisiniz.

Öğeleri numaralandırırken sipariş edebilirsiniz:

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

2.0 çerçevesi içinde, öğeleri sıralamak için önce bir listeye koymanız gerekir:

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

Sıralı Sözlük için:

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

Ürünler eklendikleri sırayla iade edilir.


5

İlişkilendirilebilir diziler (hash tabloları olarak da bilinir) sırasızdır, bu da öğelerin hayal edilebilecek herhangi bir şekilde sıralanabileceği anlamına gelir.

ANCAK, dizi anahtarlarını (yalnızca anahtarları) getirebilir, alfabetik olarak sıralayabilir (bir sıralama işlevi aracılığıyla) ve sonra üzerinde çalışabilirsiniz.

Size bir C # örneği veremem çünkü dili bilmiyorum, ancak bu sizin devam etmeniz için yeterli olmalı.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.