Преобразовать сумму в совокупное выражение продукта - PullRequest
3 голосов
/ 23 января 2011

У меня есть это выражение:

group i by i.ItemId into g
select new
{
    Id = g.Key,
    Score = g.Sum(i => i.Score)
}).ToDictionary(o => o.Id, o => o.Score);

и вместо g.Sum Я хотел бы получить математический продукт, используя Aggregate.

Чтобы убедиться, что он работает так жекак .Sum (но как продукт) я попытался создать функцию Aggregate, которая бы просто возвращала сумму ...

Score = g.Aggregate(0.0, (sum, nextItem) => sum + nextItem.Score.Value)

Однако это не дает тот же результат, что и при использовании .Sum.Любые идеи почему?

nextItem.Score имеет тип double?.

Ответы [ 3 ]

3 голосов
/ 23 января 2011
public static class MyExtensions
{
    public static double Product(this IEnumerable<double?> enumerable)
    {
        return enumerable
          .Aggregate(1.0, (accumulator, current) => accumulator * current.Value);
    }
}
1 голос
/ 23 января 2011

Дело в том, что в вашем примере вы начинаете умножение с 0,0 - умножение с нуля дает ноль, в конце результат будет нулевым.

Правильно использовать свойство тождественности умножения.Хотя добавление нуля к числу оставляет число неизменным, то же самое свойство сохраняется для умножения на 1. Следовательно, правильный способ запустить агрегат продукта - это запустить умножение с числом 1.0.

0 голосов
/ 23 января 2011

Если вы не уверены в начальном значении в вашем агрегированном запросе, и он вам остро не нужен (как в этом примере), я бы порекомендовал вам вообще его не использовать.

Вы можете использоватьСовокупная перегрузка, которая не принимает начальное значение - http://msdn.microsoft.com/en-us/library/bb549218.aspx

Как это

int product = sequence.Aggregate((x, acc) => x * acc);

, которое оценивается как item1 * (item2 * (item3 * ... * itemN)).

вместо

int product = sequence.Aggregate(1.0, (x, acc) => x * acc);

Что означает 1.0 * (item1 * (item2 * (item3 * ... * itemN))).

// edit: Хотя есть одно важное отличие.Бывший бросает InvalidOperationException, когда входная последовательность пуста.Последние возвращают начальное значение, поэтому 1,0.

...