有没有更好的方法来使用LINQ聚合字典?

Jon*_*hem 8 c# linq group-by aggregate todictionary

我试图从可枚举的构建字典,但我需要一个聚合器用于所有可能重复的键.直接使用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);
    }
Run Code Online (Sandbox Code Playgroud)

我想我真的在寻找这样的东西:

IEnumerable<T>.ToDictionary( 
    /* key selector : T -> TKey */, 
    /* value selector : T -> TValue */, 
    /* duplicate resolver : IEnumerable<TValue> -> TValue */ );
Run Code Online (Sandbox Code Playgroud)

所以...

timeEntries.ToDictionary( 
    te => te.Date, 
    te => te.Hours, 
    duplicates => duplicates.Sum() );
Run Code Online (Sandbox Code Playgroud)

'解析器'可以是.First()或.Max()等等.

或类似的东西.


我有一个实现......当我正在研究时,另一个实现了答案.

矿:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

我希望已经有类似的东西,但我猜不是.那将是一个很好的补充.

感谢大家 :-)

Amy*_*y B 5

public static Dictionary<KeyType, ValueType> ToDictionary
  <SourceType, KeyType, ValueType>
(
  this IEnumerable<SourceType> source,
  Func<SourceType, KeyType> KeySelector,
  Func<SourceType, ValueType> ValueSelector,
  Func<IGrouping<KeyType, ValueType>, ValueType> GroupHandler
)
{
  Dictionary<KeyType, ValueType> result = source
    .GroupBy(KeySelector, ValueSelector)
    .ToDictionary(g => g.Key, GroupHandler);
}
Run Code Online (Sandbox Code Playgroud)

被称为:

Dictionary<DateTime, double> result = timeEntries.ToDictionary(
  te => te.Date,
  te => te.Hours,
  g => g.Sum()
);
Run Code Online (Sandbox Code Playgroud)