ลำดับขององค์ประกอบในพจนานุกรม


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

ลำดับขององค์ประกอบในพจนานุกรมไม่ได้ถูกกำหนด ความคิดของคำสั่งไม่ได้กำหนดไว้สำหรับแฮชแท็ก ดังนั้นอย่าพึ่งพาการแจกแจงตามลำดับเดียวกับที่เพิ่มองค์ประกอบลงในพจนานุกรม ไม่รับประกัน

อ้างจากเอกสาร :

เพื่อวัตถุประสงค์ในการแจงนับแต่ละรายการในพจนานุกรมจะถือว่าเป็นKeyValuePair<TKey, TValue>โครงสร้างที่แสดงถึงค่าและคีย์ ไม่ได้กำหนดลำดับการส่งคืนสินค้า


1
แต่มี OrderedDictionary
Peter Mortensen

28

หากคุณต้องการองค์ประกอบสั่งใช้OrderedDictionary hastable / พจนานุกรมธรรมดาจะถูกเรียงลำดับตามความหมายของรูปแบบการจัดเก็บเท่านั้น


10
OrderDictionary ส่วนใหญ่ผิด ไม่ได้เรียงลำดับตามคีย์หรือค่า แต่เป็นดัชนีภายใน SortedDictionary คือคำสั่งในลักษณะที่ผู้ใช้สามารถจัดการได้ (คีย์เริ่มต้น)
Offler

3
คำถามคือถามเกี่ยวกับการเรียงลำดับตามตัวอักษร (สมมติว่าผู้ถามกำลังพูดถึงคีย์) พจนานุกรมแบบเรียงลำดับหากฉันเข้าใจเอกสารอย่างถูกต้องจะคายองค์ประกอบตามลำดับที่แทรกนั่นคือไม่ใช่ตามตัวอักษร แต่ใช้ดัชนีภายใน SortedDictionary น่าจะเหมาะที่สุดสำหรับคำถามของผู้ใช้
Mattpm

28

คุณสามารถใช้SortedDictionaryสำหรับสิ่งนั้นได้เสมอ โปรดทราบว่าพจนานุกรมจะเรียงลำดับตามคีย์ตามค่าเริ่มต้นเว้นแต่จะมีการระบุตัวเปรียบเทียบ

ฉันไม่แน่ใจเกี่ยวกับการใช้OrderedDictionaryสิ่งที่คุณต้องการเนื่องจากเอกสารระบุว่า:

องค์ประกอบของ OrderDictionary ไม่ได้จัดเรียงตามคีย์ซึ่งแตกต่างจากองค์ประกอบของคลาส SortedDictionary


สิ่งสำคัญคือต้องทราบว่าSortedDictionary<K,V>มีการใช้งานเป็น Binary Search Tree ซึ่งทำให้การดำเนินงานมีเวลาและความซับซ้อนของพื้นที่แตกต่างกันเมื่อเทียบกับแฮชแท็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

อาร์เรย์ที่เชื่อมโยงกัน (aka, ตารางแฮช) ไม่ได้เรียงลำดับซึ่งหมายความว่าสามารถจัดลำดับองค์ประกอบในแบบใดก็ได้เท่าที่จะเป็นไปได้

อย่างไรก็ตามคุณสามารถดึงคีย์อาร์เรย์ (เฉพาะคีย์) เรียงลำดับตามตัวอักษร (ผ่านฟังก์ชั่นการจัดเรียง) จากนั้นดำเนินการตามนั้น

ฉันไม่สามารถให้ตัวอย่าง C # กับคุณได้เพราะฉันไม่รู้ภาษา แต่ก็น่าจะเพียงพอสำหรับคุณที่จะดำเนินการต่อไป

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.