Thứ tự của các phần tử trong Từ điển


107

Câu hỏi của tôi là về cách liệt kê các thành phần Từ điển

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

Các phần tử sẽ được liệt kê theo thứ tự nào? Tôi có thể buộc thứ tự phải theo thứ tự bảng chữ cái không?


Câu trả lời:


125

Thứ tự của các phần tử trong từ điển là không xác định. Khái niệm thứ tự đơn giản không được định nghĩa cho các hashtable. Vì vậy, đừng dựa vào việc liệt kê theo thứ tự như các phần tử đã được thêm vào từ điển. Điều đó không được đảm bảo.

Trích dẫn từ tài liệu :

Đối với mục đích liệt kê, mỗi mục trong từ điển được coi như một KeyValuePair<TKey, TValue>cấu trúc đại diện cho một giá trị và khóa của nó. Thứ tự mà các mặt hàng được trả lại là không xác định.



28

Nếu bạn muốn các phần tử được sắp xếp theo thứ tự, hãy sử dụng một OrderedDictionary . Một hastable / từ điển thông thường chỉ được sắp xếp theo một số nghĩa của bố cục lưu trữ.


10
Trong hầu hết các trường hợp, OrderedDictionary là sai. Nó không được sắp xếp theo khóa hoặc giá trị, mà theo chỉ mục nội bộ. SortedDictionary là một trong những thứ được sắp xếp theo cách người dùng có thể thao tác (khóa mặc định)
Offler

2
Câu hỏi đang hỏi về việc sắp xếp theo thứ tự bảng chữ cái (giả sử người hỏi đang nói về khóa). Một từ điển có thứ tự, nếu tôi hiểu tài liệu một cách chính xác, sẽ rút ra các phần tử theo thứ tự chúng được chèn vào, tức là không theo thứ tự bảng chữ cái, mà sử dụng chỉ mục bên trong. SortedDictionary có lẽ phù hợp nhất cho câu hỏi của người dùng.
mattpm 15/03/18

28

Bạn luôn có thể sử dụng SortedDictionarycho điều đó. Lưu ý rằng từ điển được sắp xếp theo Khóa, theo mặc định, trừ khi một trình so sánh đã được chỉ định.

Tôi hoài nghi về việc sử dụng OrderedDictionarycho những gì bạn muốn vì tài liệu nói rằng:

Các phần tử của lớp OrderDictionary không được sắp xếp theo khóa, không giống như các phần tử của lớp SortedDictionary.


Điều quan trọng cần lưu ý SortedDictionary<K,V>là được triển khai dưới dạng Cây tìm kiếm nhị phân, cung cấp cho các hoạt động của nó độ phức tạp về thời gian và không gian khác nhau so với dựa trên bảng băm Dictionary<K,V>. Nếu người dùng cần một O(1)cấu trúc bảng băm chèn / xóa và cũng muốn lặp lại các phần tử theo thứ tự khóa thì dict.Keys.OrderBy( k => k ).Select( k => dict[k] )thay vào đó họ nên (với chi phí O(n)không gian và O( n log n )thời gian) cho OrderBy()(sẽ cần đệm toàn bộ bộ sưu tập khóa trong danh sách nội bộ ).
Đài

12

Các mục sẽ được trả về theo thứ tự chúng được lưu trữ vật lý trong từ điển, điều này phụ thuộc vào mã băm và thứ tự các mục được thêm vào. Do đó, thứ tự sẽ có vẻ ngẫu nhiên và khi việc triển khai thay đổi, bạn không bao giờ được phụ thuộc vào thứ tự giữ nguyên.

Bạn có thể sắp xếp các mục khi liệt kê chúng:

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

Trong khuôn khổ 2.0, trước tiên bạn phải đặt các mục trong một danh sách để sắp xếp chúng:

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

Đối với một OrderDictionary:

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

Các mặt hàng được trả lại theo thứ tự được thêm vào.


5

Các mảng liên kết (hay còn gọi là bảng băm) không có thứ tự, có nghĩa là các phần tử có thể được sắp xếp theo bất kỳ cách nào có thể tưởng tượng được.

TUY NHIÊN, bạn có thể tìm nạp các khóa mảng (chỉ các khóa), sắp xếp theo thứ tự bảng chữ cái (thông qua một hàm sắp xếp) và sau đó làm việc trên đó.

Tôi không thể cung cấp cho bạn một mẫu C # vì tôi không biết ngôn ngữ, nhưng điều này là đủ để bạn tự tiếp tục.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.