Wo ist die LINQ-Erweiterungsmethode „Fold“?

93

Ich habe in den Linq-Beispielen von MSDN eine nette Methode namens Fold () gefunden, die ich verwenden möchte. Ihr Beispiel:

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

Leider kann ich dies weder in ihrem Beispiel noch in meinem eigenen Code kompilieren lassen, und ich kann nirgendwo anders in MSDN (wie Enumerable- oder Array-Erweiterungsmethoden) finden, die diese Methode erwähnen. Der Fehler, den ich bekomme, ist ein einfacher alter Fehler "Ich weiß nichts darüber":

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

Ich verwende andere Methoden, von denen ich glaube, dass sie von Linq stammen (wie Select () und Where ()), und ich verwende "System.Linq", daher denke ich, dass alles in Ordnung ist.

Existiert diese Methode wirklich in C # 3.5, und wenn ja, was mache ich falsch?

Ken
quelle
3
Schauen Sie sich den Brotkrumenpfad * auf der Beispielseite an, auf die Sie verwiesen haben - er bezieht sich auf C # 3 als zukünftiges Produkt. Zukünftige Produkte ändern sich häufig vor dem Versand. Wie die anderen genannten, siehe Enumerable.Aggregate und viel Spaß. :) * Visual C # Developer Center> Startseite> Produktinformationen> Zukünftige Versionen> 101 LINQ-Beispiele> Aggregatoperatoren
Curt Nichols

Antworten:

124

Sie sollten die AggregateErweiterungsmethode verwenden:

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

Weitere Informationen finden Sie unter MSDN . Hier können Sie einen seedund dann einen Ausdruck angeben , um aufeinanderfolgende Werte zu berechnen.

Jason
quelle
4
Es sollte beachtet werden, dass Sie auch keinen Samen haben müssen. Wenn Sie die Überladung aufrufen, die keinen Startwert hat, wird das erste Element in der Liste als anfänglicher Aggregatwert verwendet und das Funcwird erst aufgerufen, wenn das zweite Element erreicht ist. Siehe: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher
Es ist keine Falte, wenn ich richtig verstehe: / Die Falte sollte beide Argumente unterschiedlichen Typs akzeptieren. Zum Beispiel könnte man als erstes Argument eine Zeichenfolge verwenden und als zweites Argument irgendetwas mit ToString(), um so eine Textdarstellung des gesamten Containers zurückzugeben.
Hi-Angel
@ Hi-Angel, nein, das Beispiel ist in der Tat eine Falte. Der <double>Typparameter wird vom Compiler nur automatisch abgeleitet und ist daher nicht erforderlich.
Kdbanman
1
@ Hi-Angel, pund elemkann jeder Typ sein, den du magst. Sehen Sie diese Überlastung, wie in diesem Beispiel verwendet
kdbanman
1
@kdbanman errr, ⁺¹, es ist wirklich interessant, warum es damals bei mir nicht funktioniert hat…: / Du hast recht, es funktioniert.
Hi-Angel
41

Fold (auch bekannt als Reduce) ist der Standardbegriff der funktionalen Programmierung. Aus irgendeinem Grund wurde es in LINQ Aggregate genannt .

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Richard Berg
quelle
9
Aggregat ist ein bekannter Begriff im OO- und SQL-Bereich.
Adam Robinson
3
Das Schlüsselwort CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) war mir nicht bekannt. Lernen Sie jeden Tag etwas Neues.
Richard Berg
5
Komisch, ich habe noch nie "Aggregat" außerhalb von SQL gehört. WP hat eine Liste en.wikipedia.org/wiki/Fold_(higher-order_function) von ein paar Dutzend Sprachen und C # ist die einzige, die es "Aggregate" nennt. "Reduzieren" ist der klare Gewinner, gefolgt von "Fold" für die ML-Familie und "Inject" für Smalltalk und Freunde.
Ken
12
Der Name ist eine Frage seiner Funktionalität; Wie es implementiert wird, ist irrelevant. Und FWIW, linke Falten werden, wenn möglich, iterativ implementiert ... in funktionalen Sprachen normalerweise über Schwanzrekursion. Und C # hat keine richtige Falte, was teilweise darauf zurückzuführen ist, dass ein dummer Name ausgewählt wurde - wenn auch nicht so schlecht wie "Auswählen" für "Karte" - und vorhandene Funktionstechnologie ignoriert wurde. Aggregat ist ein bekannter Begriff im OO-Bereich ... nein, überhaupt nicht.
Jim Balter
9
Um fair zu sein, ich denke nicht, dass Microsoft die vorhandene funktionale Technologie oder Terminologie missachtet, sondern die Ausrichtung auf den Datenbankzugriff und die SQL-Terminologie, mit der viele Unternehmensprogrammierer wahrscheinlich besser vertraut sind als mit Begriffen der funktionalen Programmierung.
RavuAlHemio