2010-06-07 6 views
4

J'ai une collection dictionnaire comme bleow:Comment supprimer des entrées d'un dictionnaire en utilisant la valeur

mydic.addvalue(key1, val1) 
mydic.addvalue(key2, val1) 
mydic.addvalue(key3, val1) 
mydic.addvalue(key4, val2) 
mydic.addvalue(key5, val2) 

du dictionnaire ci-dessus, je veux supprimer toutes les entrées où la valeur == « val1 », de sorte que la résultat aurait seulement l'entrée suivante:

mydic.addvalue(key4, val2) 
mydic.addvalue(key5, val2) 

Mon VB code source est VS2008 et ciblé pour 3,5

+1

Et les types de clé et de valeur sont? –

+0

C# ou VB.NET? Je suis confus. – dtb

+0

@user: ce n'est pas un dictionnaire C#. C'est la classe .NET Framework 'Dictionary '. –

Répondre

12

Un non du val1 -LINQ réponse basée sur un commentaire de l'utilisateur.

private static void RemoveByValue<TKey,TValue>(Dictionary<TKey, TValue> dictionary, TValue someValue) 
{ 
    List<TKey> itemsToRemove = new List<TKey>(); 

    foreach (var pair in dictionary) 
    { 
     if (pair.Value.Equals(someValue)) 
      itemsToRemove.Add(pair.Key); 
    } 

    foreach (TKey item in itemsToRemove) 
    { 
     dictionary.Remove(item); 
    } 
} 

Exemple d'utilisation:

Dictionary<int, string> dictionary = new Dictionary<int, string>(); 
dictionary.Add(1, "foo"); 
dictionary.Add(2, "foo"); 
dictionary.Add(3, "bar"); 
string someValue = "foo"; 
RemoveByValue(dictionary, someValue); 

mise en garde Comme avec les autres réponses: si votre valeur détermine l'égalité par référence, vous aurez besoin de faire un travail supplémentaire. Ceci est juste une base.

+0

"Si votre valeur détermine l'égalité par référence, vous aurez besoin de faire un travail supplémentaire, ce n'est qu'une base." -> Salut pouvez-vous élaborer sur ce que vous entendez par "si votre valeur détermine l'égalité par référence"? – BKSpurgeon

+1

@BKSpurgeon, cela signifie qu'il vérifie si deux variables se réfèrent littéralement à la même instance. Image 'Foo a = nouveau Foo(); Foo b = new Foo(); 'Tant que a et b contiennent des références à un Foo vide, ils ne se réfèrent pas au * même * Foo. Dans 'Foo a = new Foo(); Foo b = a; ', a et b font référence à la même instance. Si vous avez besoin de l'exemple précédent pour comparer comme égal, vous devez faire plus de travail, ce qui peut impliquer de remplacer Equals et GetHashCode dans la classe, ou de fournir un IEqualityCompare pour la classe. –

12

Vous devez d'abord trouver toutes les clés pour lesquelles la valeur associée est val1:

var keysToRemove = mydic.Where(kvp => kvp.Value == val1) 
         .Select(kvp => kvp.Key) 
         .ToArray(); 

vous pouvez supprimer chacune de ces touches:

foreach (var key in keysToRemove) 
{ 
    mydic.Remove(key); 
} 
+4

Ceci. Mais (@user) gardez à l'esprit que vous devrez faire un travail supplémentaire pour l'égalité si la TValue est un type de référence (à moins que vous ne fassiez que comparer des références, c'est-à-dire). De plus, '.ToArray()' ou '.ToList()' est absolument nécessaire pour parcourir les résultats dans un foreach * et * modifier le dictionnaire original. –

+0

Merci pour votre réponse rapide. Je sais que cela peut sembler idiot, mais qu'est-ce que le kvp? puisque je n'ai jamais travaillé sur linQ – user350233

+1

@user, dans ce cas, il est simplement un raccourci pour KeyValuePar. Mais le nom lui-même est sans importance dans ce contexte, il pourrait être * n'importe quoi *. Regardez dans lambdas, mais la courte version courte est celle dans '(kvp => kvp.Value == val1)', 'kvp' est le nom de l'argument fourni (dans ce cas un KeyValuePair), et' kvp.Value = = val1' est l'expression qui est vraie ou fausse. En effet, une clause LINQ Where utilise une fonction qui accepte un paramètre typé et renvoie un booléen. –

3

Vous pouvez également utiliser

var x= (from k in mydic 
      where k.Value != val1 
      select k).ToDictionary(k=>k.key); 

x sera pas de

+1

Mais ce sera aussi un nouveau dictionnaire. Toute référence au dictionnaire original serait désormais inutile à moins d'être désintéressée des clés/valeurs qui ont été supprimées (ou ajoutées, modifiées, etc.). –

+0

tirer, vous avez raison. – kd7

+0

Une meilleure solution serait la première var keys = (à partir de d dans mydic où d.Value == "val1" sélectionnez d.Key).Lister(); Ford (clé de chaîne dans les clés) } – kd7

1
foreach(var key in dict.AllKeys.ToArray()) 
{ 
    if(...) 
     //remove key or something 
} 
0

La réponse est ancienne mais c'est comme ça que je fais la même chose sans créer un autre dictionnaire.

foreach (KeyValuePair<TKey, TValue> x in MyDic) { 

    if (x.Value == "val1")) 
    { MyDic.Remove(x.Key); } 
} 
Questions connexes