Estoy intentando construir un diccionario a partir de un enumerable, pero necesito un agregador para todas las claves potencialmente duplicadas. El uso de ToDictionary() directamente causaba ocasionalmente claves duplicadas.¿Existe alguna forma mejor de agregar un diccionario utilizando LINQ?
En este caso, tengo un montón de entradas de tiempo ({DateTime Date, double Hours}), y si se producen varias entradas de tiempo en el mismo día, quiero el tiempo total para ese día. Es decir, un agregador personalizado, que me dará una clave única para una entrada de diccionario.
¿Hay una mejor manera de hacerlo que esta?
(Esto funciona.)
private static Dictionary<DateTime, double> CreateAggregatedDictionaryByDate(IEnumerable<TimeEntry> timeEntries)
{
return
timeEntries
.GroupBy(te => new {te.Date})
.Select(group => new {group.Key.Date, Hours = group.Select(te => te.Hours).Sum()})
.ToDictionary(te => te.Date, te => te.Hours);
}
creo que realmente estoy buscando algo como esto:
IEnumerable<T>.ToDictionary(
/* key selector : T -> TKey */,
/* value selector : T -> TValue */,
/* duplicate resolver : IEnumerable<TValue> -> TValue */);
así que ...
timeEntries.ToDictionary(
te => te.Date,
te => te.Hours,
duplicates => duplicates.Sum());
El 'resolutor 'podría ser. Primero() o .Max() o lo que sea.
O algo similar.
Tuve una implementación ... y apareció otra en las respuestas mientras trabajaba en ella.
Mina:
public static Dictionary<TKey, TValue> ToDictionary<T, TKey, TValue>(
this IEnumerable<T> input,
Func<T, TKey> keySelector,
Func<T, TValue> valueSelector,
Func<IEnumerable<TValue>, TValue> duplicateResolver)
{
return input
.GroupBy(keySelector)
.Select(group => new { group.Key, Value = duplicateResolver(group.Select(valueSelector)) })
.ToDictionary(k => k.Key, k => k.Value);
}
Tenía la esperanza de que había algo como eso ya, pero creo que no. Eso sería un buen complemento.
Gracias a todos :-)
¿Quiere decir que desea uniquify la tecla, o quiere quitar los DUP? – Abel
He actualizado la descripción. Intentando agregar los duplicados para hacerlos únicos, y luego construir un diccionario a partir de eso. –