Filtrar valores de un diccionario Genérico de C#


Tengo un diccionario de C#, Dictionary<Guid, MyObject> que necesito filtrar basado en una propiedad de MyObject.

Por ejemplo, quiero eliminar todos los registros del diccionario donde MyObject.BooleanProperty = false. ¿Cuál es la mejor manera de lograr esto?

Author: Fiona - myaccessible.website, 2010-01-25

4 answers

Dado que el diccionario implementa IEnumerable<KeyValuePair<Key, Value>>, solo puede usar donde:

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

Para recrear un nuevo diccionario si lo necesita, use el método ToDictionary.

 48
Author: Lee,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-03-01 13:17:07

Si no le importa crear un nuevo diccionario con los elementos deseados y tirar el viejo, simplemente intente:

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

Si no puede crear un nuevo diccionario y necesita modificar el antiguo por alguna razón (como cuando está referenciado externamente y no puede actualizar todas las referencias:

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

Tenga en cuenta que ToList es necesario aquí ya que está modificando la colección subyacente. Si cambia la colección subyacente, el enumerador que trabaja en ella consultará los valores será inutilizable y lanzará una excepción en la siguiente iteración del bucle. ToList almacena en caché los valores antes de alterar el diccionario.

 79
Author: Mehrdad Afshari,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-25 10:59:21

Simplemente puede usar la cláusula Linq where:

var filtered = from kvp in myDictionary
               where !kvp.Value.BooleanProperty
               select kvp
 7
Author: Oded,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-01-25 10:52:16

He añadido el siguiente método de extensión para mi proyecto que le permite filtrar 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;
        }
    );
}

Uso:

IDictionary<int, Person> oldPeople = personIdToPerson.KeepWhen(p => p.age > 29);
 0
Author: aaaaaa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-28 04:54:31