Dov'è il metodo di estensione LINQ "Fold"?


94

Ho trovato negli esempi Linq di MSDN un metodo accurato chiamato Fold () che desidero utilizzare. Il loro esempio:

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

Sfortunatamente, non riesco a farlo compilare, né nel loro esempio né nel mio codice, e non riesco a trovare nessun altro in MSDN (come i metodi di estensione Enumerable o Array) che menzionano questo metodo. L'errore che ricevo è un semplice vecchio errore "non so nulla di questo":

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

Sto usando altri metodi che credo provengano da Linq (come Select () e Where ()), e sto "usando System.Linq", quindi penso che sia tutto OK.

Questo metodo esiste davvero in C # 3.5 e, in tal caso, cosa sto facendo di sbagliato?


3
Controlla il percorso delle briciole di pane * nella pagina degli esempi a cui hai fatto riferimento: si riferisce a C # 3 come un prodotto futuro. I prodotti futuri cambiano spesso prima della spedizione. Come gli altri menzionati, vedi Enumerable. Aggrega e divertiti. :) * Centro per sviluppatori di Visual C #> Home> Informazioni sul prodotto> Versioni future> 101 esempi LINQ> Operatori aggregati
Curt Nichols,

Risposte:


125

Ti consigliamo di utilizzare il Aggregatemetodo di estensione:

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

Vedere MSDN per ulteriori informazioni. Consente di specificare una seede quindi un'espressione per calcolare i valori successivi.


4
Va notato che non devi nemmeno avere un seme. Se chiami l'overload che non ha valore di inizializzazione, il primo elemento nell'elenco viene utilizzato come valore aggregato iniziale e Funcviene chiamato solo una volta raggiunto il secondo elemento. Vedi: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher

Non è fold se ho capito bene: / Il fold dovrebbe accettare entrambi gli argomenti di diverso tipo. Ad esempio, come primo argomento si potrebbe usare una stringa e come secondo argomento con qualsiasi cosa ToString(), restituire così una rappresentazione testuale dell'intero contenitore.
Hi-Angel il

@ Ciao Angelo, no, l'esempio in effetti è una piega. Il <double>parametro di tipo viene semplicemente dedotto automaticamente dal compilatore e quindi non necessario.
kdbanman

1
@ Hi-Angel, pe elempuò essere il tipo che preferisci. Vedi questo sovraccarico come usato in questo esempio
kdbanman

1
@kdbanman errr, ⁺¹, è davvero interessante il motivo per cui in passato non funzionava per me…: / Hai ragione, funziona.
Hi-Angel

41

Fold (aka Reduce) è il termine standard della programmazione funzionale. Per qualsiasi motivo, è stato chiamato Aggregate in LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);

9
Aggregato è un termine più familiare nei regni OO e SQL.
Adam Robinson,

3
Non era a conoscenza della parola chiave CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Impara qualcosa di nuovo ogni giorno.
Richard Berg,

5
Divertente, non ho mai sentito "aggregare" al di fuori di SQL. WP ha un elenco en.wikipedia.org/wiki/Fold_(higher-order_function) di un paio di dozzine di lingue e C # è l'unico che lo chiama "Aggregate". "Reduce" è il chiaro vincitore, seguito da "Fold" per la famiglia ML e "Inject" per Smalltalk e amici.
Ken il

12
Il nome dipende dalla sua funzionalità; il modo in cui viene implementato è irrilevante. E FWIW, le pieghe a sinistra vengono implementate in modo iterativo quando possibile ... nei linguaggi funzionali di solito tramite la ricorsione in coda. E C # non ha una piega corretta, il che è in parte una conseguenza della scelta di un nome stupido - sebbene non così male come "seleziona" per "mappa" - e dell'ignoranza della tecnologia funzionale esistente. Quanto al fatto che Aggregate è un termine più familiare nel regno OO ... no, per niente.
Jim Balter

9
Per essere onesti, non penso che sia il disprezzo di Microsoft per la tecnologia o la terminologia funzionale esistente, ma il suo orientamento verso l'accesso al database e la terminologia di SQL, che molti programmatori aziendali conoscono probabilmente più dei termini di programmazione funzionale.
RavuAlHemio
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.