Onde está o método de extensão LINQ “dobrado”?

94

Encontrei nos exemplos do Linq do MSDN um método bacana chamado Fold () que desejo usar. O exemplo deles:

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

Infelizmente, não consigo fazer isso para compilar, nem em seu exemplo ou em meu próprio código, e não consigo encontrar nenhum outro lugar no MSDN (como métodos de extensão Enumerable ou Array) que mencionem esse método. O erro que recebo é um erro "não sei nada sobre isso":

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

Estou usando outros métodos que acredito vir do Linq (como Select () e Where ()), e estou "usando System.Linq", então acho que está tudo bem.

Esse método realmente existe no C # 3.5 e, em caso afirmativo, o que estou fazendo de errado?

Ken
fonte
3
Confira a trilha de migalhas * na página de amostras que você referiu - ela se refere ao C # 3 como um produto futuro. Os produtos futuros costumam mudar antes de serem enviados. Como os outros mencionados, consulte Enumerable.Aggregate e divirta-se. :) * Visual C # Developer Center> Home> Product Information> Future Versions> 101 Amostras LINQ> Aggregate Operators
Curt Nichols

Respostas:

125

Você vai querer usar o Aggregatemétodo de extensão:

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

Consulte MSDN para obter mais informações. Ele permite que você especifique um seede, em seguida, uma expressão para calcular valores sucessivos.

Jason
fonte
4
Deve-se notar que você também não precisa ter uma semente. Se você chamar a sobrecarga que não tem semente, o primeiro elemento da lista é usado como o valor agregado inicial e Funcsó é chamado quando o segundo elemento é alcançado. Consulte: msdn.microsoft.com/en-us/library/vstudio/…
Josh Gallagher
Não é fold, se bem entendi: / O fold deve aceitar ambos os argumentos de tipos diferentes. Por exemplo, um poderia como o primeiro arg usar uma string, e como o segundo arg qualquer coisa com ToString(), assim retornar uma representação de texto de todo o contêiner.
Hi-Angel
@ Hi-Angel, não, o exemplo é na verdade uma dobra. O <double>parâmetro de tipo é apenas inferido automaticamente pelo compilador e, portanto, não é necessário.
kdbanman
1
@ Hi-Angel, pe elempode ser do tipo que você quiser. Veja esta sobrecarga conforme usada neste exemplo
kdbanman
1
@kdbanman errr, ⁺¹, é realmente interessante porque naquela época não funcionava para mim…: / ​​Você está certo, funciona.
Hi-Angel
41

Dobrar (também conhecido como Reduzir) é o termo padrão da programação funcional. Por alguma razão, ele foi denominado Aggregate no LINQ.

double product = doubles.Aggregate(1.0, (runningProduct, nextFactor) => runningProduct* nextFactor);
Richard Berg
fonte
9
Agregar é um termo mais familiar nos domínios OO e SQL.
Adam Robinson
3
Não conhecia a palavra-chave CREATE AGGREGATE ( msdn.microsoft.com/en-us/library/ms182741.aspx ) Aprenda algo novo todos os dias.
Richard Berg
5
Engraçado, nunca ouvi "agregação" fora do SQL. WP tem uma lista en.wikipedia.org/wiki/Fold_(higher-order_function) de algumas dúzias de linguagens e C # é o único que o chama de "agregado". "Reduzir" é o vencedor claro, seguido por "Dobrar" para a família ML e "Injetar" para Smalltalk e amigos.
Ken,
12
O nome é uma questão de funcionalidade; como é implementado é irrelevante. E FWIW, dobras à esquerda são implementadas iterativamente quando possível ... em linguagens funcionais geralmente via recursão de cauda. E C # não tem uma dobra correta, o que é em parte consequência de escolher um nome estúpido - embora não tão ruim quanto "selecionar" para "mapa" - e ignorar a tecnologia funcional existente. Quanto a Agregar ser um termo mais familiar no reino OO ... não, de forma alguma.
Jim Balter
9
Para ser justo, não acho que seja o desprezo da Microsoft pela tecnologia ou terminologia funcional existente, mas sua orientação em relação ao acesso ao banco de dados e à terminologia SQL, com a qual muitos programadores corporativos estão provavelmente mais familiarizados do que os termos de programação funcional.
RavuAlHemio