2008-10-21 12 views
5

Tôi tin rằng tôi không thể dựa vào thứ tự các mục được thêm vào từ điển cho mục đích đếm.Các hạng mục của lớp bộ sưu tập dotnet nào có thể được liệt kê trong "thứ tự bổ sung" và được truy xuất qua khóa?

Có một lớp học (chung nếu có thể) mà các mục nào có thể được thêm bằng khóa và có thể liệt kê theo thứ tự bổ sung hoặc có thể truy lục bằng khóa không?

Làm rõ: Tôi không muốn liệt kê trong Thứ tự khóa. Tôi muốn liệt kê theo thứ tự bổ sung. Mà là để nói rằng tôi muốn để có thể lấy các mục thông qua liệt kê trên một FIFO (đầu tiên trong đầu tiên ra) cơ sở.

Trả lời

3

Trước tiên, dựa trên giả định chính của bạn, bạn chính xác. Từ điển thông thường không đảm bảo về thứ tự liệt kê.

Thứ hai, bạn cần cẩn thận khi đi theo số SortedDictionary với tuyến đường tùy chỉnh IComparer. Bộ so sánh được sử dụng cho sự bình đẳng chính cũng như sắp xếp bộ sưu tập. Tức là, sử dụng IComparer dựa trên thứ tự bổ sung, bạn có thể gặp khó khăn khi truy xuất phần tử từ giá trị khóa SortedDictionary, nó có thể bị mất trong cây (đó là sự hậu thuẫn của từ điển được sắp xếp).

Nếu bạn sẵn sàng sử dụng lộ trình Thư viện lớp chung C5, bạn có thể lấy số dặm tốt từ số HashedLinkedList<KeyValuePair<T>> hoặc HashedLinkedList<T> nếu T là tự khóa. Bạn có thể tạo một IEqualityComparer sẽ hoạt động trên khóa để tạo mã băm. Sau đó, lấy giá trị thực tế, bạn có thể sử dụng Find(ref T x) với nguyên mẫu x (có lẽ chỉ có khóa được đặt) sẽ tìm thấy số T được lưu trữ và trả lại bằng cách tham chiếu trong O (1) time vs. O (log) n) với số SortedDictionary. Đồng thời, được hỗ trợ bởi một LinkedList, nó được đảm bảo liệt kê theo thứ tự bổ sung (và bạn có thể xác định hướng nào bạn muốn thông qua C5's IDirectedEnumerable).

Hy vọng điều đó sẽ hữu ích.

4

Bạn có thể đạt được hiệu quả bạn muốn chỉ bằng cách sử dụng List lưu trữ khóa theo thứ tự bổ sung. Sau đó, bạn có thể liệt kê danh sách đó theo thứ tự và lấy các giá trị từ Dictionary.

Tuy nhiên, nếu bạn muốn làm tất cả điều này với một loại bộ sưu tập hiện có, tôi không biết loại nào thực hiện điều này mà không cần cung cấp bộ so sánh hoặc không có khóa. Trước đây, bạn có thể thử SortedDictionary và sau đó, bạn có thể lấy một bộ sưu tập mới từ KeyedCollection (không hoàn toàn chắc chắn rằng điều này sẽ duy trì thứ tự mà không cần so sánh để bạn cần thử nghiệm để xác nhận điều đó).

0

Bạn có thể tạo lớp chung của riêng mình (và lấy từ lớp <,> hoặc SortedDictionary <,>) và triển khai phiên bản GetEnumerator của riêng bạn() trong đó bạn có thể sắp xếp từ điển theo khóa và trả về giá trị được sắp xếp (hoặc nếu bạn sử dụng SortedDictionary thì nó đã được sắp xếp).

Bạn cũng có thể sử dụng SortedList <,>, tốt hơn và nhẹ hơn trong một số trường hợp, hãy kiểm tra MSDN để xem loại nào phù hợp nhất với nhu cầu của bạn.

+0

Tôi không theo thứ tự "Key". Tôi sau khi thêm lệnh. Mặc dù tôi có quan điểm của bạn về kế thừa và ghi đè GetEnumerator. –

0

Chủ đề hơi cũ nhưng tôi đang tìm kiếm một bộ sưu tập có cùng hành vi (giữ nguyên thứ tự các mục được thêm) VÀ có thể lập chỉ mục bộ sưu tập trên một khóa. Câu trả lời là lớp trừu tượng KeyedCollection <>! (trong không gian tên System.Collections.ObjectModel) Tôi chạy một thử nghiệm đơn giản với một từ điển và keyedcollection này bằng cách thêm một loạt các lần, loại bỏ một từ giữa và thêm lại mục. KeyedCollection thêm mục mới vào cuối, từ điển đặt nó ở vị trí ban đầu của nó (tôi đoán một số loại băm đang diễn ra ở đó)

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