Ich habe ein C # -Wörterbuch, Dictionary<Guid, MyObject>
das basierend auf einer Eigenschaft von gefiltert werden muss MyObject
.
Zum Beispiel möchte ich alle Datensätze aus dem Wörterbuch entfernen, wo MyObject.BooleanProperty = false
. Was ist der beste Weg, um dies zu erreichen?
c#
generics
dictionary
filtering
Fiona - myaccessible.website
quelle
quelle
Wenn Sie kein neues Wörterbuch mit den gewünschten Elementen erstellen und das alte wegwerfen möchten, versuchen Sie einfach:
Wenn Sie kein neues Wörterbuch erstellen können und das alte aus irgendeinem Grund ändern müssen (z. B. wenn es extern referenziert wird und Sie nicht alle Referenzen aktualisieren können:
foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList()) dic.Remove(item.Key);
Beachten Sie, dass
ToList
dies hier erforderlich ist, da Sie die zugrunde liegende Sammlung ändern. Wenn Sie die zugrunde liegende Auflistung ändern, ist der Enumerator, der daran arbeitet, um die Werte abzufragen, unbrauchbar und löst bei der nächsten Schleifeniteration eine Ausnahme aus.ToList
speichert die Werte zwischen, bevor das Wörterbuch überhaupt geändert wird.quelle
Sie können einfach die Linq where-Klausel verwenden:
var filtered = from kvp in myDictionary where !kvp.Value.BooleanProperty select kvp
quelle
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); }
quelle
Ich habe die folgende Erweiterungsmethode für mein Projekt hinzugefügt, mit der Sie ein IDictionary filtern können.
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; } ); }
Verwendung:
IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);
quelle
Hier ist eine allgemeine Lösung, die nicht nur für boolesche Eigenschaften der Werte funktioniert.
Methode
Erinnerung: Erweiterungsmethoden müssen in statischen Klassen platziert werden. Vergessen Sie nicht die
using System.Linq;
Anweisung oben in der Quelldatei./// <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); }
Verwendung
Beispiel:
var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);
quelle