4

I have a dictionary

private readonly Dictionary<string, WebResponse> _myDictionary;

Lets assume I have 10 values in the dictionary currently. I can able to add some values into it also I can delete the values based on the key present in the dictionary similar to below.

Remove:

_myDictionary.Remove(Key); 

where key is a string variable.

Is that possible to delete more than one key at a time if the values matches for more than one key. I have keys like {KAAR1, KAAR2, KAAR3, ABCDEF}. Now I need to delete all the keys which contains "KAAR". Is that possible to do.

Kindly help.

Priya
  • 69
  • 5
  • 6
    Try this: `_myDictionary.Where(x => x.Key.Contains("KAAR")).ToList().ForEach(kvp => _myDictionary.Remove(kvp.Key));`. – Enigmativity Jul 17 '18 at 06:24
  • @Enigmativity why don't you add this as answer. It looks a pretty good idea to me – Ahmad Jul 17 '18 at 06:29
  • 2
    Check this question for more ways to do the same https://stackoverflow.com/questions/469202/best-way-to-remove-multiple-items-matching-a-predicate-from-a-c-sharp-dictionary – Karan Jul 17 '18 at 06:33
  • @Enigmativity - Your answer worked without any problem. Thank you very much! – Priya Jul 17 '18 at 07:08

3 Answers3

9

Try this:

_myDictionary
    .Where(x => x.Key.Contains("KAAR"))
    .ToList()
    .ForEach(kvp => _myDictionary.Remove(kvp.Key));
Enigmativity
  • 113,464
  • 11
  • 89
  • 172
  • Why `ToList()`? – Chayim Friedman Jul 17 '18 at 06:51
  • @חייםפרידמן Probably because this way it doesn't create a *new* Dictionary – Fabjan Jul 17 '18 at 06:56
  • 1
    @חייםפרידמן Because where outputs in IEnumerable on which we can't apply Foreach loop. Thats why it is needed to convert to LIST. – Ahmad Jul 17 '18 at 06:59
  • @חייםפרידמן - The `.ToList()` call also forces the full enumeration of the dictionary so that the `.Remove(...)` calls won't change the dictionary while enumerating. And, as Ahmad says, to get access to the `.ForEach(...)` extension method. – Enigmativity Jul 17 '18 at 07:12
  • Thanks. I undestand. – Chayim Friedman Jul 17 '18 at 07:19
  • A small hint: Using extension methods are highly beneficial for lists and dictionaries because it allows the use of syntax like this: `ListObj.YourMethod ();` And the question seems to demand a general solution applicable for generic types. – Battle Jul 17 '18 at 08:25
  • @Battle - Sorry, I don't understand. What do you mean by `ListObj.YourMethod();`? – Enigmativity Jul 17 '18 at 11:58
  • @Enigmativity - It wasn't directed at you personally, and was not meant as any criticism - your answer is great. I just wanted to point out that all of that can be wrapped into an extension method using generics... and with the answer below I also added the code for it. – Battle Jul 17 '18 at 12:13
0

Below is the answer given by the user @Enigmavitivity!! Added as seprate answer to mark as a correct one.

_myDictionary.Where(x => x.Key.Contains("KAAR")).ToList().ForEach(kvp => _myDictionary.Remove(kvp.Key));
Priya
  • 69
  • 5
0

I expanded the answer of @Enigmativity to provide two generic versions as extension methods.

/// <summary> Removes all duplicate values after the first occurrence. </summary>
public static void RemoveDuplicates<T, V> (this Dictionary<T, V> dict)
{
    List<V> L = new List<V> ();
    int i = 0;
    while (i < dict.Count)
    {
        KeyValuePair<T, V> p = dict.ElementAt (i);
        if (!L.Contains (p.Value))
        {
            L.Add (p.Value);
            i++;
        }
        else
        {
            dict.Remove (p.Key);
        }
    }
}

With a dictionary of values (ignoring keys): 0, 1, 2, 3, 5, 1, 2, 4, 5. Result: 0, 1, 2, 3, 5, 4.

/// <summary> Removes all values which have any duplicates. </summary>
public static void RemoveAllDuplicates<T, V> (this Dictionary<T, V> dict)
{
    List<V> L = new List<V> ();
    int i = 0;
    while (i < dict.Count)
    {
        KeyValuePair<T, V> p = dict.ElementAt (i);
        if (!L.Contains (p.Value))
        {
            L.Add (p.Value);
            i++;
        }
        else
        {
            dict.Where (j => Equals (j.Value, p.Value)).ToList ().ForEach (j => dict.Remove (j.Key));
        }
    }
}

With a dictionary of values (ignoring keys): 0, 1, 2, 3, 5, 1, 2, 4, 5. Result: 3, 4.

The methods are optimized to prevent multiple executions of the .Where operation (otherwise each duplicate would have n executions of it, where all after the first one is obsolete). Code is tested and working.

Battle
  • 786
  • 10
  • 17