Де метод розширення LINQ у складеному вигляді?


95

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

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

На жаль, я не можу змусити це скомпілювати, ні в їх прикладі, ні у власному коді, і я не можу знайти де-небудь ще в MSDN (наприклад, Enumerable або Array extension extension), де згадується цей метод. Помилка, яку я отримую, є простою старою помилкою "нічого про це не знаю":

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 як майбутній продукт. Майбутні вироби часто змінюються ще до їх поставки. Як і інші згадані, див. «Незліченні». Зберіть і розважтесь. :) * Центр розробників Visual C #> Домашня сторінка> Інформація про продукт> Майбутні версії> Зразки 101 LINQ> Сукупні оператори
Curt Nichols

Відповіді:


126

Ви захочете використовувати 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

@ Hi-Angel, ні, приклад насправді є складкою. Параметр <double>type просто визначається автоматично компілятором і, отже, не є необхідним.
kdbanman

1
@ Привіт-Ангел, pі elemможе бути будь-якого типу, який тобі подобається. Перегляньте це перевантаження, як у цьому прикладі
kdbanman

1
@kdbanman помилка, ⁺¹, справді цікаво, чому в той час це не працювало у мене ...: / Ви маєте рацію, це працює.
Hi-Angel

42

Fold (він же Reduce) - стандартний термін функціонального програмування. З якоїсь причини в LINQ він отримав назву Aggregate .

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 # є єдиним, хто називає його "Сукупний". "Зменшити" - це явний переможець, за ним "Fold" для сім'ї ML та "Inject" для Smalltalk та друзів.
Кен

12
Назва - це питання його функціональності; як це реалізовано, не має значення. І FWIW, ліві складки реалізуються ітераційно, коли це можливо ... у функціональних мовах, як правило, через рекурсію хвоста. І C # не має правильної складки, що частково є наслідком вибору дурного імені - хоч і не такого поганого, як "select" для "map" - та ігнорування існуючих функціональних технологій. Що стосується агрегату, який є більш звичним терміном у сфері ОО ... ні, зовсім не.
Jim Balter

9
Чесно кажучи, я не думаю, що це ігнорування корпорацією Майкрософт існуючих функціональних технологій чи термінології, а орієнтація на доступ до баз даних та термінологію SQL, які, мабуть, знайомі багатьом корпоративним програмістам, аніж терміни функціонального програмування.
RavuAlHemio
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.