2011-09-22 36 views
9

Tôi có một cấu trúc từ điển, với nhiều cặp khóa giá trị bên trong.Cách chèn làm phần tử đầu tiên trong từ điển?

myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

Từ điển của tôi được sử dụng làm nguồn dữ liệu để kiểm soát một số. Trong danh sách thả xuống của điều khiển, tôi thấy các mục như sau:

key1 
key2 
key3 

Thứ tự trông giống với từ điển của tôi. Tôi biết từ điển không giống như arrayList - bạn có thể nhận được chỉ mục. Tôi không thể sử dụng được sắp xếpDictionary. Bây giờ tôi cần phải bổ sung thêm một cặp giá trị key vào từ điển này tại một số điểm của chương trình của tôi và tôi hy vọng nó có tác dụng tương tự như tôi làm điều này:

myDict.Add(newKey, newValue); 
myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

Nếu tôi làm điều này, tôi biết newKey sẽ hiển thị trong kiểm soát của tôi như là yếu tố đầu tiên.

Tôi có một ý tưởng để tạo ra một tempDict, đưa từng cặp trong myDict để tempDict, sau đó myDict rõ ràng, sau đó thêm cặp lại như thế này:

myDict.Add(newKey, newValue); 
myDict.Add(key1, value1); 
myDict.Add(key2, value2); 
myDict.Add(key3, value3); 

Có cách tốt hơn thế này?

Cảm ơn!

Trả lời

19

Dictionary<K,V> không không có đơn đặt hàng. Bất kỳ sự bảo trì trật tự nhận thức nào cũng là cơ hội (và một tạo phẩm của một sự triển khai cụ thể bao gồm, nhưng không giới hạn, thứ tự chọn và số lần chọn của nhóm).

Đây là những phương pháp tiếp cận (chỉ sử dụng Base Class Libraries BCL) Tôi biết về:

  1. Lookup<K,V>
    • .NET4, bất biến, có thể ánh xạ phím để nhiều giá trị (xem các bản sao trong xây dựng)
  2. OrderedDictionary
    • Cũ, không chung chung, dự kiến ​​Từ điển perfor vọt Mance (hai cách tiếp cận khác là O(n) cho "nhận được (key)/set (key)")
  3. List<KeyValuePair<K,V>>
    • .NET2/3 sao, có thể thay đổi, legwork hơn, có thể ánh xạ phím để nhiều giá trị (xem bản sao trong các hình chèn)

Mã hóa vui vẻ.


Tạo băm dữ liệu cấu trúc duy trì trật tự chèn là thực sự chỉ một sửa đổi nhỏ của một thực hiện băm chuẩn (Ruby tại băm duy trì trật tự chèn); Tuy nhiên, điều này đã không được thực hiện trong .NET cũng không, quan trọng hơn, nó là một phần của hợp đồng Dictionary/IDictionary.

+0

Bạn có ý nghĩa gì khi "chèn đồng hồ" trên Lookup ? Bạn có nghĩa là người ta cần phải cẩn thận khi chèn các giá trị vào một tra cứu ? Nếu vậy, thì điều đó không đúng, bởi vì Lookup là không thay đổi. – phoog

+0

@phoog Vì nó * có thể * xử lý một khóa duy nhất cho nhiều giá trị có thể dẫn đến các tình huống không thể xảy ra với từ điển. Từ ngữ không lý tưởng. –

+0

+1 cho câu trả lời nổi bật này –

1

Không sử dụng từ điển - không đảm bảo thứ tự của các phím sẽ không thay đổi khi bạn thêm các yếu tố khác.Thay vào đó, hãy xác định lớp học Pair cho các cặp khóa-giá trị của bạn (xem tại đây What is C# analog of C++ std::pair? để biết ví dụ) và sử dụng List<Pair> cho nguồn dữ liệu của bạn. List có hoạt động Insert mà bạn có thể sử dụng để chèn các phần tử mới vào bất kỳ đâu trong danh sách của mình.

+0

nhưng điều khiển của tôi cần từ điển để cung cấp nguồn dữ liệu và chúng tôi không muốn thay đổi điều khiển. – spspli

+1

@spspli: những gì bác sĩ giỏi nói là bạn không được bỏ qua những điều cơ bản của 'Dictionary '. Vì vậy, hoặc bạn thay đổi cấu trúc dữ liệu của bạn hoặc bạn sống với một bộ sưu tập không có thứ tự. – user7116

+3

Khi bạn muốn kiểm soát hiển thị các phần tử theo thứ tự cụ thể, danh sách và chỉ nguồn dữ liệu được phép là từ điển - không cung cấp thứ tự cụ thể - thì điều khiển của bạn được thiết kế sai và bạn không thể mong đợi tìm giải pháp cho vấn đề. Vì vậy, hoặc là bạn thay đổi kiểm soát của bạn, sử dụng một điều khiển khác nhau hoặc tìm hiểu thêm về kiểm soát của bạn nếu có một cách khác để nhận được thông tin đặt hàng một nơi nào đó từ bên ngoài vào nó. –

2

Từ trang MSDN vào từ điển (TKey, TValue):

Đối với mục đích của điều tra, từng hạng mục trong từ điển được coi là một KeyValuePair < (Tất < (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ục được trả về là không xác định.

Tôi giả sử bạn không thể sử dụng SortedDictionary vì điều khiển phụ thuộc vào nguồn dữ liệu của bạn là từ điển. Nếu điều khiển mong đợi cả loại từ điển và dữ liệu được sắp xếp, điều khiển cần được sửa đổi, bởi vì hai tiêu chí đó mâu thuẫn với nhau. Bạn phải sử dụng loại dữ liệu khác nếu bạn cần chức năng sắp xếp/sắp xếp. Tùy thuộc vào hành vi không xác định được yêu cầu cho sự cố.

5

Bạn không thể làm điều đó với lớp học Dictionary. Nó đang làm việc trong ví dụ của bạn bởi vì một quirk trong cách cấu trúc dữ liệu được thực hiện. Cấu trúc dữ liệu thực sự lưu trữ các mục trong thứ tự thời gian trong một mảng và sau đó sử dụng một mảng khác để lập chỉ mục vào mảng nhập. Các bảng liệt kê dựa trên mảng nhập. Đó là lý do tại sao nó xuất hiện để được đặt hàng trong trường hợp của bạn. Nhưng, nếu bạn áp dụng một loạt các hoạt động loại bỏ và chèn, bạn sẽ nhận thấy thứ tự này bị nhiễu loạn.

Sử dụng KeyCollection để thay thế. Nó cung cấp O (1) truy xuất bởi cả khóa và chỉ mục và duy trì thứ tự thời gian.

+0

+1 Ước gì tôi biết về KeyCollection trước đây (nhưng tại sao nó lại trong không gian tên ComponentModel và tại sao nó dựa vào việc mở rộng?: - /) –

+0

@pst: Tôi không có ý tưởng ... câu hỏi hay. –

+0

+1 [KeyedCollection] (http://msdn.microsoft.com/en-us/library/ms132438.aspx) chỉ là những gì tôi đang tìm kiếm! – Ben

1

Từ điển Không được sử dụng để sắp xếp các đối tượng, nó nên được sử dụng để tìm kiếm các đối tượng. tôi sẽ đề nghị một cái gì đó khác nếu bạn muốn có nó sắp xếp các đối tượng quá.

Nếu bạn mở rộng Từ điển, không có quy tắc nào ngăn nó trộn danh sách của bạn.

Các vấn đề liên quan