2009-03-19 4 views
7

Tôi đang lưu trữ một loạt ID mục được cho là duy nhất được coi là khóa và vị trí tệp làm giá trị trong bảng băm trong khi duyệt qua bảng. Trong khi tôi đang chạy qua nó, tôi cần phải chắc chắn rằng cặp khóa/vị trí là duy nhất hoặc ném một thông báo lỗi. Tôi có Hashtable thành lập và đang tải các giá trị, nhưng không chắc chắn những gì để kiểm tra:Làm thế nào để kiểm tra xem C# Hashtable có chứa cặp khóa/giá trị cụ thể không?

Hashtable check_for_duplicates = new HashTable(); 
foreach (object item in items) 
{ 
    if (check_for_duplicates.ContainsKey(item["ItemID"]) && 
     //what goes here? Would be contains item["Path"] as the value for the key) 
    { 
     //throw error 
    } 
} 
+0

Thực ra, Ken Browning đánh tôi với cùng một câu trả lời trong 20 giây. Đưa ra câu trả lời cho anh ta. –

+0

anh ấy đã làm, nhưng câu trả lời của bạn đã hoàn thành hơn – Brian

Trả lời

11

Hãy thử điều này:

Hashtable check_for_duplicates = new HashTable(); 
foreach (object item in items) 
{ 
    if (check_for_duplicates.ContainsKey(item["ItemID"]) && 
     check_for_duplicates[item["ItemID"]].Equals(item["Path"])) 
    { 
     //throw error 
    } 
} 

Ngoài ra, nếu bạn đang sử dụng .NET 2.0 hoặc cao hơn, hãy xem xét sử dụng Generics, như thế này:

List<Item> items; // Filled somewhere else 

// Filters out duplicates, but won't throw an error like you want. 
HashSet<Item> dupeCheck = new HashSet<Item>(items); 

items = dupeCheck.ToList(); 

Thực ra, tôi chỉ cần kiểm tra, và có vẻ như HashSet là .NET 3.5. Một điển sẽ thích hợp hơn cho 2.0:

Dictionary<int, string> dupeCheck = new Dictionary<int, string>(); 

foreach(Item item in items) { 
    if(dupeCheck.ContainsKey(item.ItemID) && 
     dupeCheck[item.ItemID].Equals(item.Path)) { 
     // throw error 
    } 
    else { 
     dupeCheck[item.ItemID] = item.Path; 
    }  
} 
+0

Tìm thấy lỗi nhỏ: check_for_duplicates [item ["ItemID"]] == mục ["Đường dẫn"] phải là check_for_duplicates [item ["ItemID"]]. Bằng (Item ["Path"]) – Brian

+0

Về HashSet; bạn có thể so sánh số đếm trong tập hợp kết quả với số lượng bộ sưu tập ban đầu nếu bạn muốn tìm hiểu xem có số lần phân tách hay không. (Cảnh báo: không thực hiện.) – mquander

4

Nếu bạn đang sử dụng Dictionary thay vào đó, phương pháp TryGetValue sẽ giúp đỡ. Tôi không nghĩ rằng có một cách thực sự tốt hơn cho các lớp học Hashtable.

object value; 
if (dic.TryGetValue("key", out value) && value == thisValue) 
    // found duplicate 
+0

không gian tên nào tôi nên sử dụng để kích hoạt từ điển? Chúng không nằm trong bất kỳ vùng tên mặc định nào. – Brian

+0

Lớp Từ điển (http://msdn.microsoft.com/en-us/library/xfhwa508.aspx) đã được giới thiệu trong .NET 2.0 và được đặt trong không gian tên System.Collections.Generic. –

3
if (check_for_duplicates.ContainsKey(item["ItemID"]) && 
    check_for_duplicates[item["ItemID"]] == item["Path"]) 
{ 
    //throw error 
} 
1

Nó kinda phụ thuộc những gì các mảng mục là ... bạn sẽ muốn một cái gì đó như:

check_for_duplicates.ContainsValue(item["Path"]); 

Giả sử rằng các mục là một số hình thức tra cứu . Thực sự bạn cần phải đúc mục hoặc sử dụng hệ thống loại để thực sự truy cập bất kỳ giá trị nào thông qua chỉ mục.

+0

Tệ của tôi ... Tôi đã không nhận ra rằng có một mệnh đề AND trong câu hỏi ban đầu. – Ian

3

ContainsKey là phương pháp tốt nhất.

Nếu bạn không bị buộc phải sử dụng .NET 1.1 Tôi sẽ sử dụng Từ điển được giới thiệu trong .NET 2.0.

Nó tốt hơn nhiều so với hàm băm từ hiệu suất và được nhập mạnh mẽ.

Dictionary<string, int> betterThanAHash = new Dictionary<string, int>(); 

betterThanAHash.ContainsKey("MyKey"); 
+0

Tôi nên sử dụng không gian tên nào cho điều này? Từ điển không có trong các không gian tên mặc định tôi đang sử dụng. – Brian

+0

sau đó thêm không gian tên cho từ điển =) – Svish

+0

@Brian - System.Collections.Generic – TheMissingLINQ

2
Hashtable check_for_duplicates = new HashTable(); 

foreach (object item in items) 
{ 
    if (check_for_duplicates.ContainsKey(item["ItemID"]) && check_for_duplicates[item["ItemID"]] == item["Path"]) 
    { 
     //throw error 
    } 
} 

Tôi tin rằng đây là những gì bạn đang tìm kiếm.

EDIT - Hình như tôi đã bị đánh đến những cú đấm: P

+0

Hầu như, ví dụ của bạn không hoạt động (thiếu a) trên: check_for_duplicates [item ["ItemID"] – Brian

+0

Đúng vậy, nó đã được sửa . –

2

Tại sao không sử dụng một Dictionary để thay thế?

Điều đó sẽ ném một ArgumentException nếu bạn cố gắng Add một khóa đã tồn tại trong Dictionary.

Bằng cách đó bạn có thể bắt được bản sao tại thời điểm được thêm, thay vì thực hiện kiểm tra check_for_duplicates sau đó.

1

Bạn không nói bạn đang sử dụng phiên bản nào. Có một lý do bạn phải sử dụng một Hashtable vs một HashSet? Bạn sẽ không cần phải kiểm tra các bản sao nếu cấu trúc dữ liệu của bạn không cho phép chúng.Xem thêm:

http://www.vcskicks.com/csharp_data_structures2.html

Ngoài ra, vấn đề làm thế nào để thực hiện được điều tương tự trong Hashtable đã được trả lời ở đây. Tôi chỉ chỉ ra rằng bạn không cần phải làm tất cả các kiểm tra bệnh lý nếu bạn cấm nó ở nơi đầu tiên.