2009-10-28 38 views
41

Tengo un Dictionary<string, string>.Eliminar elemento en el diccionario basado en el valor

Necesito mirar dentro de ese diccionario para ver si existe un valor basado en la información de otro lugar y si existe eliminarlo.

ContainsValue simplemente dice verdadero/falso y no el índice o la clave de ese elemento.

¡Ayuda!

Gracias

EDIT: Sólo encontraron esta - ¿qué te parece?

var key = (from k in dic where string.Compare(k.Value, "two", true) == 
0 select k.Key).FirstOrDefault(); 

EDIT 2: Asimismo, sólo derribado esto que podría trabajar

foreach (KeyValuePair<string, string> kvp in myDic) 
{ 
    if (myList.Any(x => x.Id == kvp.Value)) 
     myDic.Remove(kvp.Key); 
} 
+0

I piensas que necesitas un BiDictionary. Verifique esta pregunta: http://stackoverflow.com/questions/255341/getting-key-of-value-of-a-generic-dictionary/255638#255638 –

+3

¿Lo encontró en 5 minutos? – Xinus

+0

Lo encontró en un sitio diferente – Jon

Respuesta

101

¿Está tratando de eliminar un solo valor o todos los valores coincidentes?

Si está tratando de eliminar un solo valor, ¿cómo define el valor que desea eliminar?

La razón por la que no obtiene una clave cuando consulta los valores es porque el diccionario podría contener varias claves emparejadas con el valor especificado.

Si desea eliminar todas las instancias correspondientes del mismo valor, usted puede hacer esto:

foreach(var item in dic.Where(kvp => kvp.Value == value).ToList()) 
{ 
    dic.Remove(item.Key); 
} 

Y si desea eliminar el primer caso de coincidencia, se puede consultar para encontrar el primer artículo y simplemente eliminar dicho:

var item = dic.First(kvp => kvp.Value == value); 

dic.Remove(item.Key); 

Nota: La llamadaToList() es necesario copiar los valores a una nueva colección. Si no se realiza la llamada, el ciclo modificará la colección sobre la que se está iterando, provocando que se genere una excepción en el próximo intento de iteración después de que se elimine el primer valor.

+7

El primer ejemplo de código no funciona, porque no tiene permiso para modificar la colección en el bucle foreach. –

+0

Una edición anónima eliminó parte del código necesario. Voy a poner algo de nuevo. –

+0

+1 por mencionar la información en la Nota. – Roger

2

bucle a través del diccionario para encontrar el índice y luego lo elimina.

+0

Tal como se indica en la respuesta aceptada, si elimina un elemento del diccionario mientras recorre el diccionario, arrojará un error si quedan valores en el diccionario después del que eliminó. – ammills01

6
Dictionary<string, string> source 
// 
//functional programming - do not modify state - only create new state 
Dictionary<string, string> result = source 
    .Where(kvp => string.Compare(kvp.Value, "two", true) != 0) 
    .ToDictionary(kvp => kvp.Key, kvp => kvp.Value) 
// 
// or you could modify state 
List<string> keys = source 
    .Where(kvp => string.Compare(kvp.Value, "two", true) == 0) 
    .Select(kvp => kvp.Key) 
    .ToList(); 

foreach(string theKey in keys) 
{ 
    source.Remove(theKey); 
} 
0

En mi caso utilizo este

var key=dict.FirstOrDefault(m => m.Value == s).Key; 
      dict.Remove(key); 
1

Aquí es un método que puede utilizar:

public static void RemoveAllByValue<K, V>(this Dictionary<K, V> dictionary, V value) 
    { 
     foreach (var key in dictionary.Where(
       kvp => EqualityComparer<V>.Default.Equals(kvp.Value, value)). 
       Select(x => x.Key).ToArray()) 
      dictionary.Remove(key); 
    } 
0

Usted puede utilizar lo siguiente como método de extensión

public static void RemoveByValue<T,T1>(this Dictionary<T,T1> src , T1 Value) 
    { 
     foreach (var item in src.Where(kvp => kvp.Value.Equals(Value)).ToList()) 
     { 
      src.Remove(item.Key); 
     } 
    } 
Cuestiones relacionadas