Où est la méthode d'extension LINQ «Plier»?

94

J'ai trouvé dans les échantillons Linq de MSDN une méthode soignée appelée Fold () que je veux utiliser. Leur exemple:

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

Malheureusement, je ne peux pas le faire compiler, que ce soit dans leur exemple ou dans mon propre code, et je ne trouve nulle part ailleurs dans MSDN (comme les méthodes d'extension Enumerable ou Array) qui mentionnent cette méthode. L'erreur que j'obtiens est une vieille erreur "Je ne sais rien de cette":

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

J'utilise d'autres méthodes qui, je crois, viennent de Linq (comme Select () et Where ()), et j'utilise System.Linq, donc je pense que tout va bien.

Cette méthode existe-t-elle vraiment en C # 3.5, et si oui, qu'est-ce que je fais de mal?

Ken
la source
3
Consultez le fil d'Ariane * sur la page d'exemples que vous avez référencée - il fait référence à C # 3 en tant que futur produit. Les futurs produits changent souvent avant d'être expédiés. Comme les autres mentionnés, voir Enumerable.Aggregate et amusez-vous. :) * Centre de développement Visual C #> Accueil> Informations sur le produit> Versions futures> 101 échantillons LINQ> Opérateurs d'agrégats
Curt Nichols

Réponses:

125

Vous voudrez utiliser la Aggregateméthode d'extension:

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

Consultez MSDN pour plus d'informations. Il vous permet de spécifier un seedpuis une expression pour calculer des valeurs successives.

Jason
la source
4
Il convient de noter que vous n'êtes pas obligé d'avoir une graine non plus. Si vous appelez la surcharge qui n'a pas de valeur de départ, le premier élément de la liste est utilisé comme valeur d'agrégation initiale et le Funcn'est appelé qu'une fois le deuxième élément atteint. Voir: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher
Ce n'est pas un pli si je comprends bien: / Le pli devrait accepter les deux arguments de types différents. Par exemple, on pourrait comme premier argument utiliser une chaîne, et comme second argument n'importe quoi avec ToString(), ainsi renvoyer une représentation textuelle de l'ensemble du conteneur.
Hi-Angel
@ Salut-Angel, non, l'exemple est en fait un pli. Le <double>paramètre type est simplement automatiquement déduit par le compilateur et n'est donc pas nécessaire.
kdbanman
1
@ Salut-Angel, pet elempeut être le type que vous aimez. Voir cette surcharge utilisée dans cet exemple
kdbanman
1
@kdbanman errr, ⁺¹, il est vraiment intéressant de savoir pourquoi à l'époque ça ne fonctionnait pas pour moi…: / Tu as raison, ça marche.
Hi-Angel
41

Fold (aka Réduire) est le terme standard de la programmation fonctionnelle. Pour une raison quelconque, il a été nommé Aggregate dans LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Richard Berg
la source
9
L'agrégat est un terme plus familier dans les domaines OO et SQL.
Adam Robinson
3
Ne connaissait pas le mot clé CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Apprenez quelque chose de nouveau chaque jour.
Richard Berg
5
C'est drôle, je n'ai jamais entendu "agréger" en dehors de SQL. WP a une liste en.wikipedia.org/wiki/Fold_(higher-order_function) de quelques douzaines de langues et C # est le seul qui l'appelle "Aggregate". "Réduire" est clairement le gagnant, suivi de "Fold" pour la famille ML et "Inject" pour Smalltalk et ses amis.
Ken
12
Le nom est une question de fonctionnalité; la manière dont il est mis en œuvre n'a pas d'importance. Et FWIW, les plis de gauche sont implémentés de manière itérative lorsque cela est possible ... dans les langages fonctionnels généralement via la récursivité de la queue. Et C # n'a pas de pli droit, ce qui est en partie une conséquence du choix d'un nom stupide - mais pas aussi mauvais que "sélectionner" pour "carte" - et de l'ignorance de la technologie fonctionnelle existante. Quant à l'agrégat étant un terme plus familier dans le domaine OO ... non, pas du tout.
Jim Balter
9
Pour être honnête, je ne pense pas que ce soit le mépris de Microsoft pour la technologie fonctionnelle ou la terminologie existante, mais son orientation vers l'accès aux bases de données et la terminologie SQL, que de nombreux programmeurs d'entreprise connaissent probablement plus que les termes de programmation fonctionnelle.
RavuAlHemio