2009-03-19 9 views
7

Estoy almacenando un montón de identificadores de elementos supuestamente únicos como clave y las ubicaciones de archivos como el valor en una tabla hash al atravesar una tabla. Mientras lo estoy ejecutando, necesito asegurarme de que el par de clave/ubicación sea único o arroje un mensaje de error. Tengo la tabla hash configurado y estoy cargando los valores, pero no estoy seguro de qué prueba:¿Cómo se prueba si un C Hashtable contiene un par clave/valor específico?

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

En realidad, Ken Browning me ganó con la misma respuesta en 20 segundos. Dale la respuesta. –

+0

lo hizo, pero su respuesta fue más completa – Brian

Respuesta

11

Prueba esto:

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

Además, si usted está utilizando .NET 2.0 o superior, puede utilizar los genéricos, así:

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(); 

En realidad, simplemente comprobado, y parece que HashSet es solo .NET 3.5. Un diccionario sería más apropiado para 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

Encontró un error menor: check_for_duplicates [item ["ItemID"]] == item ["Ruta"] debería ser check_for_duplicates [item ["ItemID"]]. Es igual (Item ["Ruta"]) – Brian

+0

Con respecto a HashSet; Puede comparar el recuento en el conjunto resultante con el recuento de la colección original si desea averiguar si hubo engaños. (Advertencia: no rendimiento.) – mquander

4

Si estaba utilizando Dictionary lugar, el método TryGetValue ayudaría. No creo que haya una manera realmente mejor para la clase obsoleta Hashtable.

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

¿qué espacio de nombres debería usar para habilitar Diccionarios? No están en ninguno de los espacios de nombres predeterminados. – Brian

+0

La clase de diccionario (http://msdn.microsoft.com/en-us/library/xfhwa508.aspx) se introdujo en .NET 2.0 y se encuentra en el espacio de nombres System.Collections.Generic. –

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

Depende un poco lo que es la matriz de elementos ... que querrá algo como:

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

Suponiendo que el artículo es una cierta forma de las operaciones de búsqueda . Realmente necesita lanzar elementos o usar un sistema de tipos para acceder realmente a cualquier valor a través de un índice.

+0

Mi mal ... No me había dado cuenta de que había una cláusula AND en la pregunta original. – Ian

3

ContainsKey es el mejor método.

Si no está obligado a utilizar .NET 1.1, usaría el Diccionario introducido en .NET 2.0.

Es mucho mejor que un Hashtable de rendimiento y está fuertemente tipado.

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

betterThanAHash.ContainsKey("MyKey"); 
+0

¿Qué espacio de nombre debería usar para esto? El diccionario no está en los espacios de nombres predeterminados que estoy usando. – Brian

+0

a continuación, agregar el espacio de nombres para el diccionario =) – 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 
    } 
} 

yo creo que esto es lo que estás buscando.

EDITAR - Parece que he sido golpeado por la mano: P

+0

Casi, su ejemplo no funciona bastante (falta a] en: check_for_duplicates [artículo [ "ItemID"] – Brian

+0

Eso es correcto, se ha fijado . –

2

por qué no usar un Dictionary en su lugar?

Eso lanzará una ArgumentException si intentas Add una clave que ya existe en el Dictionary.

De esta forma puede capturar el duplicado en el momento en que se lo agrega, en lugar de realizar una prueba check_for_duplicates más tarde.

1

No dijo qué versión de cosas estaba usando. ¿Hay alguna razón por la que deba usar un Hashtable frente a un HashSet? No es necesario que compruebe si hay duplicados si su estructura de datos no los permitió.Ver también:

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

Aparte de eso, la cuestión de cómo lograr lo mismo en Hashtable ya ha sido contestada aquí. Solo estoy señalando que no necesitas hacer todas las comprobaciones patológicas si lo prohibes en primer lugar.

Cuestiones relacionadas