J'ai un dictionnaire C #, Dictionary<Guid, MyObject>
que je dois filtrer en fonction d'une propriété de MyObject
.
Par exemple, je veux supprimer tous les enregistrements du dictionnaire où MyObject.BooleanProperty = false
. Quel est le meilleur moyen d'y parvenir?
Puisque Dictionary implémente IEnumerable<KeyValuePair<Key, Value>>
, vous pouvez simplement utiliser Where
:
var matches = dictionary.Where(kvp => !kvp.Value.BooleanProperty);
Pour recréer un nouveau dictionnaire si vous en avez besoin, utilisez la méthode ToDictionary
.
Si vous ne vous souciez pas de créer un nouveau dictionnaire avec les éléments désirés et de jeter l'ancien, essayez simplement:
dic = dic.Where(i => i.Value.BooleanProperty)
.ToDictionary(i => i.Key, i => i.Value);
Si vous ne pouvez pas créer un nouveau dictionnaire et que vous devez modifier l'ancien pour une raison quelconque (comme lorsqu'il est référencé en externe et que vous ne pouvez pas mettre à jour toutes les références:
foreach (var item in dic.Where(item => !item.Value.BooleanProperty).ToList())
dic.Remove(item.Key);
Notez que ToList
est nécessaire ici, car vous modifiez la collection sous-jacente. Si vous modifiez la collection sous-jacente, l'énumérateur qui y travaille pour interroger les valeurs sera inutilisable et lève une exception lors de la prochaine itération de la boucle. ToList
met en cache les valeurs avant de modifier le dictionnaire.
Vous pouvez simplement utiliser la clause Linq where:
var filtered = from kvp in myDictionary
where !kvp.Value.BooleanProperty
select kvp
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);
}
J'ai ajouté la méthode d'extension suivante pour mon projet qui vous permet de filtrer un 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;
}
);
}
Usage:
IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);
Voici une solution générale, travaillant non seulement pour les propriétés booléennes des valeurs.
Méthode
Rappel: les méthodes d'extension doivent être placées dans des classes statiques. N'oubliez pas l'instruction using System.Linq;
en haut du fichier source.
/// <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);
}
tilisation
Exemple:
var onlyWithPositiveValues = allNumbers.Filter(it => it.Value > 0);