29 votos

.net diccionario de la búsqueda y añadir / actualizar

Estoy harto de hacer bloques de código como este para varios bits de código que me han dado:

if (dict.ContainsKey[key]) {  
    dict[key] = value;  
}  
else {  
    dict.Add(key,value);  
}

y para las búsquedas (es decir, la clave -> lista de valor)

if (lookup.ContainsKey[key]) {  
    lookup[key].Add(value);  
}  
else {  
    lookup.Add(new List<valuetype>);  
    lookup[key].Add(value);  
}  

Hay otras colecciones lib o método de extensión que debo usar para hacer esto en una sola línea de código no importa cuál sea la clave y tipos de valor?

por ejemplo,

dict.AddOrUpdate(key,value)  
lookup.AddOrUpdate(key,value)

28voto

Jon Skeet Puntos 692016

Como Evgeny dice, el indizador ya van a sustituir a los actuales valores - así que si usted sólo quiere incondicionalmente establecer el valor de una clave determinada, que puede hacer

dictionary[key] = value;

El caso más interesante es el de "obtener un valor, o insertarlo si es necesario". Es fácil de hacer con un método de extensión:

public static TValue GetOrCreateValue<TKey, TValue>
    (this IDictionary<TKey, TValue> dictionary,
     TKey key,
     TValue value)
{
    return dictionary.GetOrCreateValue(key, () => value);
}

public static TValue GetOrCreateValue<TKey, TValue>
    (this IDictionary<TKey, TValue> dictionary,
     TKey key,
     Func<TValue> valueProvider)
{
    TValue ret;
    if (!dictionary.TryGetValue(key, out ret))
    {
        ret = valueProvider();
        dictionary[key] = ret;
    }
    return ret;
}

Nota el uso de un delegado para crear el valor predeterminado - que facilita escenarios como la "lista de valores"; usted no desea crear la lista vacía a menos que usted tiene que:

dict.GetOrCreateValue(key, () => new List<int>()).Add(item);

Tenga en cuenta también que esta sólo se realiza la búsqueda de una vez si la clave ya está presente - no hay necesidad de hacer una ContainsKey y , a continuación, busque el valor. Todavía se requiere de dos búsquedas cuando se trata de crear el nuevo valor, aunque.

14voto

EMP Puntos 17246

A la hora de actualizar no es necesario realizar una comprobación. Simplemente use:

dict[key] = value

Reemplazará cualquier valor existente. Al recuperar el valor lamentablemente no existe un solo método (como setdefault en Python), pero usted puede hacer su propio método de extensión. Algo como esto:

if (!lookup.TryGetValue(key, out value))
{
     value = new List<T>();
     lookup.Add(key, value);
}

4voto

Darin Dimitrov Puntos 528142

ConcurrentDictionary .NET 4.0 tiene este buen método. Usted podría también escribir un método de extensión para este.

2voto

lockwobr Puntos 191

Si se trabaja con .NET Framework 4 o posterior, puede utilizar el Método AddOrUpdate

dict.AddOrUpdate(key,value)  

agregar o actualizar es como este

dict[key] = value;

1voto

Charles Gargent Puntos 771

No estoy seguro de si hay un método como se pide, pero se podría escribir una pequeña función para esto, o usar el try catch excepción, presumiblemente, si intenta agregar un valor que ya existe se producirá una excepción. Si usted coge eso y lo ignoran... Solo una sugerencia

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X