Где находится метод расширения LINQ «Сгибание»?

95

В примерах MSDN Linq я нашел изящный метод под названием Fold (), который я хочу использовать. Их пример:

double[] doubles = { 1.7, 2.3, 1.9, 4.1, 2.9 }; 
double product = 
     doubles.Fold((runningProduct, nextFactor) => runningProduct * nextFactor); 

К сожалению, я не могу скомпилировать это ни в их примере, ни в моем собственном коде, и я не могу найти нигде в MSDN (например, методы расширения Enumerable или Array), в которых упоминается этот метод. Я получаю простую старую ошибку «ничего не знаю об этой»:

error CS1061: 'System.Array' does not contain a definition for 'Fold' and no 
extension method 'Fold' accepting a first argument of type 'System.Array' could 
be found (are you missing a using directive or an assembly reference?)

Я использую другие методы, которые, как мне кажется, происходят из Linq (например, Select () и Where ()), и я «использую System.Linq», так что я думаю, что все в порядке.

Действительно ли этот метод существует в C # 3.5, и если да, то что я делаю не так?

Кен
источник
3
Ознакомьтесь с описанием хлебных крошек * на странице примеров, на которую вы ссылались - C # 3 относится к будущему продукту. Будущие продукты часто меняются перед отправкой. Как и другие упомянутые, см. Enumerable.Aggregate и получайте удовольствие. :) * Центр разработчиков Visual C #> Главная> Информация о продукте> Будущие версии> 101 образец LINQ> Агрегатные операторы
Курт Николс,

Ответы:

127

Вы захотите использовать Aggregateметод расширения:

double product = doubles.Aggregate(1.0, (prod, next) => prod * next);

См. MSDN для получения дополнительной информации. Он позволяет вам указать, seedа затем выражение для вычисления последовательных значений.

Джейсон
источник
4
Следует отметить, что вам также не обязательно иметь семя. Если вы вызываете перегрузку, у которой нет начального числа, то первый элемент в списке используется в качестве начального агрегированного значения, и Funcвызывается только после достижения второго элемента. См .: msdn.microsoft.com/en-us/library/vstudio/…
Джош Галлахер,
Если я правильно понимаю, это не свертка: / Сгиб должен принимать оба аргумента разных типов. Например, в качестве первого аргумента можно использовать строку, а в качестве второго аргумента - что угодно с ToString(), таким образом, вернуть текстовое представление всего контейнера.
Hi-Angel
@ Привет-Ангел, нет, это на самом деле фолд. Параметр <double>типа просто автоматически определяется компилятором и поэтому не является необходимым.
kdbanman
1
@ Привет, Ангел, pи elemты можешь быть кем угодно. Посмотрите, как эта перегрузка используется в этом примере
kdbanman
1
@kdbanman errr,, действительно интересно, почему в то время это не сработало для меня…: / Вы правы, это действительно работает.
Hi-Angel
42

Свернуть (также известное как сокращение) - стандартный термин из функционального программирования. По какой-то причине он получил название Aggregate в LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Ричард Берг
источник
9
Агрегат - более знакомый термин в областях объектно-ориентированного программирования и SQL.
Адам Робинсон
3
Не знал о ключевом слове CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Узнавайте что-то новое каждый день.
Ричард Берг,
5
Забавно, я никогда не слышал «агрегат» вне SQL. В WP есть список en.wikipedia.org/wiki/Fold_(higher-order_function) пары десятков языков, и C # - единственный, который называет его «Агрегатным». "Reduce" - явный победитель, за ним следует "Fold" для семейства машинного обучения и "Inject" для Smalltalk и его друзей.
Кен
12
Название зависит от его функциональности; как это реализовано, не имеет значения. И FWIW, левые складки реализуются итеративно, когда это возможно ... в функциональных языках обычно через хвостовую рекурсию. А в C # нет правильного сгиба, что отчасти является следствием выбора глупого имени - хотя и не такого плохого, как «выбрать» для «карты» - и игнорирования существующей функциональной технологии. Что касается агрегирования, более привычного термина в объектно-ориентированной сфере ... нет, совсем нет.
Джим Балтер
9
Честно говоря, я не думаю, что Microsoft игнорирует существующие функциональные технологии или терминологию, а скорее ориентирована на доступ к базе данных и терминологию SQL, с которой многие корпоративные программисты, вероятно, более знакомы, чем термины функционального программирования.
RavuAlHemio