Filtering Values โ€‹โ€‹from a Common C # Dictionary

I have a C # dictionary, Dictionary<Guid, MyObject> , which I need to filter based on the MyObject property.

For example, I want to delete all entries from the dictionary, where MyObject.BooleanProperty = false . What is the best way to achieve this?

+59
dictionary generics c # filtering
Jan 25 '10 at
source share
6 answers

Since Dictionary implements IEnumerable<KeyValuePair<Key, Value>> , you can simply use Where :

 var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty); 

To recreate a new dictionary, if you need one, use the ToDictionary method.

+59
Jan 25 '10 at
source share

If you do not care about creating a new dictionary with the necessary items and discarding the old one, just try:

 dic = dic.Where(i => i.Value.BooleanProperty) .ToDictionary(i => i.Key, i => i.Value); 

If you cannot create a new dictionary and for some reason change the old one, for example, when it refers to external links, and you cannot update all the links:

 foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList()) dic.Remove(item.Key); 

Please note that ToList needed here since you are ToList base collection. If you change the base collection, the enumerator working on it to query the values โ€‹โ€‹will be unusable and will throw an exception in the next iteration of the loop. ToList caches values โ€‹โ€‹before changing the dictionary at all.

+87
Jan 25 '10 at 10:44
source share

You can just use Linq , where is the point:

 var filtered = from kvp in myDictionary where !kvp.Value.BooleanProperty select kvp 
+7
Jan 25 '10 at 10:45
source share
  public static Dictionary<TKey, TValue> Where<TKey, TValue>(this Dictionary<TKey, TValue> instance, Func<KeyValuePair<TKey, TValue>, bool> predicate) { return Enumerable.Where(instance, predicate) .ToDictionary(item => item.Key, item => item.Value); } 
+2
Oct 19 '18 at 3:50
source share

I added the following extension method for my project, which allows you to filter an IDictionary.

 public static IDictionary<keyType, valType> KeepWhen<keyType, valType>( this IDictionary<keyType, valType> dict, Predicate<valType> predicate ) { return dict.Aggregate( new Dictionary<keyType, valType>(), (result, keyValPair) => { var key = keyValPair.Key; var val = keyValPair.Value; if (predicate(val)) result.Add(key, val); return result; } ); } 

Using:

 IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29); 
0
Sep 28 '17 at 4:54 on
source share

method

Reminder: extension methods should be placed in static classes.

  /// <summary> /// Creates a filtered copy of this dictionary, using the given predicate. /// </summary> public static Dictionary<K, V> Filter<K, V>(this Dictionary<K, V> dict, Predicate<KeyValuePair<K, V>> pred) { return dict.Where(it => pred(it)).ToDictionary(it => it.Key, it => it.Value); } 

using

Example:

  var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0); 
0
Jul 01 '19 at 18:00
source share



All Articles