Я пытаюсь построить словарь из перечислимого, но мне нужен агрегатор для всех потенциально дублирующих ключей. Непосредственное использование ToDictionary () иногда приводило к дублированию ключей.
В этом случае у меня есть несколько записей времени ({DateTime Date, double Hours}), и если несколько записей времени происходят в один и тот же день, я хочу указать общее время для этого дня. То есть пользовательский агрегатор, который даст мне уникальный ключ для словарной статьи.
Есть ли лучший способ сделать это, чем этот?
(Это работает.)
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);
}
Мне кажется, я действительно ищу что-то вроде этого:
IEnumerable<T>.ToDictionary(
/* key selector : T -> TKey */,
/* value selector : T -> TValue */,
/* duplicate resolver : IEnumerable<TValue> -> TValue */ );
так ...
timeEntries.ToDictionary(
te => te.Date,
te => te.Hours,
duplicates => duplicates.Sum() );
'resolver' может быть .irst () или .Max () или что-то еще.
Или что-то подобное.
У меня была одна реализация ... и другая появилась в ответах, когда я работал над ней.
Mine:
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);
}
Я надеялся, что что-то подобное уже было, но, думаю, нет. Это было бы хорошим дополнением.
Спасибо всем: -)