Я пытаюсь создать словарь из перечислимого, но мне нужен агрегатор для всех возможных дубликатов ключей. Использование ToDictionary() напрямую вызывало повторяющиеся ключи.Есть ли лучший способ для объединения словаря с помощью LINQ?
В этом случае у меня есть куча записей времени ({DateTime Date, double Hours}), и если в тот же день происходит несколько записей времени, я хочу общее время для этого дня. I.e., настраиваемый агрегатор, который даст мне уникальный ключ для записи словаря.
Есть ли лучший способ сделать это, чем это?
(Это работает.)
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());
«распознаватель 'может быть .First() или .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);
}
Я надеялся, что там было что-то подобное уже, но я не думаю. Это было бы приятным дополнением.
Спасибо всем :-)
ли вы имеете в виду, что вы хотите uniquify ключ, или вы хотите, чтобы удалить Dups? – Abel
Я обновил описание. Попытка объединить дубликаты, чтобы сделать их уникальными, а затем построить словарь из этого. –