Gdzie jest metoda rozszerzenia LINQ „składana”?

95

Znalazłem w próbkach Linq MSDN zgrabną metodę o nazwie Fold (), której chcę użyć. Ich przykład:

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

Niestety, nie mogę tego skompilować, ani w ich przykładzie, ani we własnym kodzie i nie mogę znaleźć nigdzie indziej w MSDN (jak metody rozszerzenia Enumerable lub Array), które wspominają o tej metodzie. Pojawiający się błąd to zwykły stary błąd „nie wiem nic o tym”:

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?)

Używam innych metod, które, jak sądzę, pochodzą z Linq (jak Select () i Where ()), i używam System.Linq, więc myślę, że to wszystko w porządku.

Czy ta metoda naprawdę istnieje w C # 3.5, a jeśli tak, to co robię źle?

Rozpoznać
źródło
3
Sprawdź ślad okruchów chleba * na stronie z przykładami, do której się odwołujesz - odnosi się do C # 3 jako przyszłego produktu. Przyszłe produkty często zmieniają się, zanim zostaną wysłane. Podobnie jak inne wspomniane powyżej, zobacz Enumerable.Agregate and have fun. :) * Visual C # Developer Center> Strona główna> Informacje o produkcie> Przyszłe wersje> 101 przykładów LINQ> Aggregate Operators
Curt Nichols,

Odpowiedzi:

127

Będziesz chciał użyć Aggregatemetody rozszerzenia:

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

Aby uzyskać więcej informacji, zobacz MSDN . Pozwala określić a, seeda następnie wyrażenie w celu obliczenia kolejnych wartości.

Jason
źródło
4
Należy zauważyć, że nie musisz też mieć nasionka. W przypadku wywołania przeciążenia, które nie ma ziarna, pierwszy element na liście jest używany jako początkowa wartość zagregowana, a Funcwywoływana jest dopiero po osiągnięciu drugiego elementu. Zobacz: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher
To nie jest fałdowanie, jeśli dobrze rozumiem: / Fold powinien akceptować oba argumenty różnych typów. Np. Można by jako pierwszy argument użyć łańcucha, a jako drugiego wszystkiego z czym ToString(), w ten sposób zwrócić reprezentację tekstową całego kontenera.
Hi-Angel,
@ Cześć Angel, nie, przykład to pas. <double>Parametr typ jest po prostu automatycznie wnioskować przez kompilator, a zatem nie jest konieczne.
kdbanman
1
@ Cześć Anioł, pi elemmoże być dowolnym typem. Zobacz to przeciążenie użyte w tym przykładzie
kdbanman
1
@kdbanman errr, ⁺¹, to naprawdę interesujące, dlaczego kiedyś to nie działało dla mnie…: / Masz rację, to działa.
Hi-Angel
42

Fold (inaczej Reduce) to standardowy termin z programowania funkcjonalnego. Z jakiegoś powodu otrzymał nazwę Aggregate w LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Richard Berg
źródło
9
Agregat jest terminem bardziej znanym w dziedzinach OO i SQL.
Adam Robinson
3
Nie znałem słowa kluczowego CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ). Codziennie ucz się czegoś nowego.
Richard Berg
5
Zabawne, nigdy nie słyszałem „agregacji” poza SQL. WP ma listę en.wikipedia.org/wiki/Fold_(higher-order_function) kilkudziesięciu języków, a C # jest jedynym, który nazywa ją „Aggregate”. Wyraźnym zwycięzcą jest „Reduce”, a za nim „Fold” dla rodziny ML oraz „Inject” dla Smalltalk i przyjaciół.
Ken
12
Nazwa jest kwestią funkcjonalności; sposób jej wdrożenia nie ma znaczenia. A FWIW, lewe fałdy są implementowane iteracyjnie, jeśli to możliwe ... w językach funkcjonalnych, zwykle poprzez rekurencję ogonową. A C # nie ma odpowiedniego zagięcia, co jest po części konsekwencją wybrania głupiej nazwy - choć nie tak złej jak „wybierz” dla „mapy” - i ignorowania istniejącej technologii funkcjonalnej. Jeśli chodzi o określenie Aggregate jako bardziej znanego terminu w dziedzinie OO ... nie, wcale.
Jim Balter
9
Aby być uczciwym, nie sądzę, że Microsoft lekceważy istniejącą technologię lub terminologię funkcjonalną, ale jego orientację na dostęp do bazy danych i terminologię SQL, którą wielu programistów korporacyjnych prawdopodobnie zna lepiej niż terminy programowania funkcjonalnego.
RavuAlHemio