Isso pode parecer ridículo, mas não consegui encontrar uma explicação realmente boa sobre Aggregate
.
Bom significa curto, descritivo, abrangente, com um exemplo pequeno e claro.
A definição mais fácil de entender de Aggregate
é que ela executa uma operação em cada elemento da lista, levando em consideração as operações anteriores. Ou seja, ele executa a ação no primeiro e no segundo elemento e leva o resultado adiante. Em seguida, opera no resultado anterior e no terceiro elemento e leva adiante. etc.
Exemplo 1. Somando números
var nums = new[]{1,2,3,4};
var sum = nums.Aggregate( (a,b) => a + b);
Console.WriteLine(sum); // output: 10 (1+2+3+4)
Isso adiciona 1
e 2
faz 3
. Em seguida, adiciona 3
(resultado do anterior) e 3
(próximo elemento em sequência) a fazer 6
. Então adiciona 6
e 4
faz 10
.
Exemplo 2. Crie um CSV a partir de uma matriz de strings
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(csv); // Output a,b,c,d
Isso funciona da mesma maneira. Concatene a
uma vírgula e b
faça a,b
. Em seguida, concatena a,b
com uma vírgula e c
fazer a,b,c
. e assim por diante.
Exemplo 3. Multiplicando números usando uma semente
Para completar, há uma sobrecarga de Aggregate
que tem um valor de semente.
var multipliers = new []{10,20,30,40};
var multiplied = multipliers.Aggregate(5, (a,b) => a * b);
Console.WriteLine(multiplied); //Output 1200000 ((((5*10)*20)*30)*40)
Muito parecido com os exemplos acima, isso começa com um valor de 5
e o multiplica pelo primeiro elemento da sequência que 10
fornece um resultado de 50
. Este resultado é transportado e multiplicado pelo próximo número na sequência 20
para obter um resultado de 1000
. Isso continua pelos 2 elementos restantes da sequência.
Exemplos ao vivo: http://rextester.com/ZXZ64749
Documentos: http://msdn.microsoft.com/en-us/library/bb548651.aspx
Termo aditivo
O exemplo 2, acima, usa concatenação de cadeias para criar uma lista de valores separados por vírgula. Esta é uma maneira simplista de explicar o uso de Aggregate
qual era a intenção desta resposta. No entanto, se usar esta técnica para criar uma grande quantidade de dados separados por vírgula, seria mais apropriado usar ae StringBuilder
isso é totalmente compatível com o Aggregate
uso da sobrecarga propagada para iniciar o StringBuilder
.
var chars = new []{"a","b","c", "d"};
var csv = chars.Aggregate(new StringBuilder(), (a,b) => {
if(a.Length>0)
a.Append(",");
a.Append(b);
return a;
});
Console.WriteLine(csv);
Exemplo atualizado: http://rextester.com/YZCVXV6464
[1,2,3,4]
será[3,3,4]
, em seguida,[6,4]
e, finalmente[10]
. Mas, em vez de retornar uma matriz de um único valor, você obtém o próprio valor.TakeWhile
entãoAggregate
e isso é o beatuty de extensões Enumerable - elas são facilmente encadeadas. Então você acaba comTakeWhile(a => a == 'a').Aggregate(....)
. Veja este exemplo: rextester.com/WPRA60543var csv = string.Join(",", chars)
(sem necessidade de agregadores ou construtores de string) - mas sim, eu sei que o ponto da resposta era dar um exemplo de uso de agregados para que seja legal. Mas eu ainda queria mencionar que não é recomendado para cordas acaba de entrar, já existe um método dedicado para isso ....var biggestAccount = Accounts.Aggregate((a1, a2) => a1.Amount >= a2.Amount ? a1 : a2);
Depende parcialmente de qual sobrecarga você está falando, mas a idéia básica é:
(currentValue, sequenceValue)
em(nextValue)
currentValue = nextValue
currentValue
Você pode achar útil o
Aggregate
post na minha série Edulinq - ele inclui uma descrição mais detalhada (incluindo as várias sobrecargas) e implementações.Um exemplo simples é usar
Aggregate
como alternativa aCount
:Ou talvez somando todos os comprimentos de cadeias em uma sequência de cadeias:
Pessoalmente, raramente acho
Aggregate
útil - os métodos de agregação "personalizados" geralmente são bons o suficiente para mim.fonte
O agregado super curto funciona como uma dobra em Haskell / ML / F #.
Um pouco mais .Max (), .Min (), .Sum (), .Average () todos iteram sobre os elementos em uma sequência e os agregam usando a respectiva função agregada. .Aggregate () é um agregador generalizado, pois permite ao desenvolvedor especificar o estado inicial (também conhecido como seed) e a função agregada.
Eu sei que você pediu uma breve explicação, mas achei que os outros deram algumas respostas curtas. Achei que talvez você se interessasse por uma mais longa.
Versão longa com código Uma maneira de ilustrar o que pode ser mostrado como você implementa o Desvio Padrão de Amostra uma vez usando o foreach e outra vez o .Aggregate. Nota: Não priorizei o desempenho aqui, por isso itero várias vezes desnecessariamente na coleção
Primeiro, uma função auxiliar usada para criar uma soma de distâncias quadráticas:
Em seguida, faça uma amostra do desvio padrão usando o ForEach:
Em seguida, uma vez usando .Aggregate:
Observe que essas funções são idênticas, exceto por como calcula sumOfQuadraticDistance:
Versus:
Então, o que .Aggregate faz é que ele encapsula esse padrão agregador e eu espero que a implementação de .Aggregate seja algo parecido com isto:
O uso das funções de desvio padrão seria algo como isto:
Na minha humilde opinião
Então. Agregado ajuda a legibilidade? Em geral, eu amo o LINQ porque acho que .Onde, .Select, .OrderBy e assim por diante ajudam bastante a legibilidade (se você evitar. O agregado precisa estar no Linq por motivos de integridade, mas, pessoalmente, não estou tão convencido de que o.
fonte
SampleStandardDeviation_Aggregate()
eSampleStandardDeviation_ForEach()
não pode serprivate
(por padrão na ausência de um qualificador de acesso), então deve ter sido acumulados por um ou outropublic
ouinternal
, parece-meUma imagem vale mais que mil palavras
Enumerable.Aggregate tem três sobrecargas:
Sobrecarga 1:
Exemplo:
Essa sobrecarga é simples, mas possui as seguintes limitações:
caso contrário , a função lançará um
InvalidOperationException
.Sobrecarga 2:
Exemplo:
Essa sobrecarga é mais geral:
bIn
).nesse caso, a função produzirá o valor de semente como resultado.
Sobrecarga 3:
A terceira sobrecarga não é muito útil para IMO.
O mesmo pode ser escrito de forma mais sucinta usando a sobrecarga 2 seguida por uma função que transforma seu resultado.
fonte
Aggegate
.net que leva aFunc<T, T, T>
.seed
aplica a função acumuladora N -1 vezes; enquanto as outras sobrecargas (que não levam aseed
) aplicar a função de acumulador N vezes.O agregado é basicamente usado para agrupar ou resumir dados.
De acordo com o MSDN "Função agregada Aplica uma função acumuladora em uma sequência".
Exemplo 1: Adicione todos os números em uma matriz.
* important: O valor agregado inicial por padrão é o elemento 1 na sequência da coleção. ou seja: o valor inicial total da variável será 1 por padrão.
explicação da variável
total: manterá o valor total (valor agregado) retornado pela função.
nextValue: é o próximo valor na sequência da matriz. Este valor é então adicionado ao valor agregado, ou seja, total.
Exemplo 2: adicione todos os itens em uma matriz. Defina também o valor inicial do acumulador para começar a adicionar a partir de 10.
explicação dos argumentos:
o primeiro argumento é o inicial (valor inicial, ou seja, valor inicial) que será usado para iniciar a adição com o próximo valor na matriz.
o segundo argumento é uma função que é uma função que leva 2 int.
1.total: será o mesmo que antes do valor total (valor agregado) retornado pela função após o cálculo.
2.nextValue:: é o próximo valor na sequência da matriz. Este valor é então adicionado ao valor agregado, ou seja, total.
A depuração desse código também fornecerá uma melhor compreensão de como o trabalho agregado.
fonte
Aprendi muito com a resposta de Jamiec .
Se a única necessidade é gerar uma sequência CSV, você pode tentar isso.
Aqui está um teste com 1 milhão de strings
O código fonte está aqui
fonte
Além de todas as ótimas respostas aqui, eu também o usei para guiar um item por uma série de etapas de transformação.
Se uma transformação for implementada como a
Func<T,T>
, você poderá adicionar várias transformações aList<Func<T,T>>
e usarAggregate
para percorrer uma instância deT
cada etapa.Um exemplo mais concreto
Você deseja obter um
string
valor e orientá-lo por uma série de transformações de texto que podem ser construídas programaticamente.Isso criará uma cadeia de transformações: Remova os espaços iniciais e finais -> remova o primeiro caractere -> remova o último caractere -> converta para maiúsculas. As etapas dessa cadeia podem ser adicionadas, removidas ou reordenadas conforme necessário, para criar qualquer tipo de pipeline de transformação necessário.
O resultado final desse pipeline específico é o que
" cat "
se torna"A"
.Isso pode se tornar muito poderoso quando você perceber que
T
pode ser qualquer coisa . Isso pode ser usado para transformações de imagem, como filtros, usandoBitMap
como exemplo;fonte
O método agregado é um método de extensão para coleções genéricas. O método agregado aplica uma função a cada item de uma coleção. Não apenas aplica uma função, mas leva seu resultado como valor inicial para a próxima iteração. Portanto, como resultado, obteremos um valor calculado (min, max, avg ou outro valor estatístico) de uma coleção.
Portanto, o método agregado é uma forma de implementação segura de uma função recursiva.
Seguro , porque a recursão irá percorrer cada item de uma coleção e não podemos obter nenhuma suspensão de loop infinito por condição de saída incorreta. Recursivo , porque o resultado da função atual é usado como parâmetro para a próxima chamada de função.
Como funciona:
que está fazendo a mesma coisa que esta função:
fonte
Esta é uma explicação sobre o uso
Aggregate
em uma API do Fluent, como a Classificação Linq.e vamos ver que queremos implementar uma função de classificação que utilize um conjunto de campos, isso é muito fácil de usar, em
Aggregate
vez de um loop for, como este:E podemos usá-lo assim:
fonte
Todo mundo deu sua explicação. Minha explicação é assim.
O método agregado aplica uma função a cada item de uma coleção. Por exemplo, vamos ter a coleção {6, 2, 8, 3} e a função Add (operator +) que ele faz (((6 + 2) +8) +3) e retorna 19
Neste exemplo, é passado o método chamado Add em vez da expressão lambda.
fonte
Uma definição curta e essencial pode ser essa: o método de extensão Linq Aggregate permite declarar um tipo de função recursiva aplicada aos elementos de uma lista, cujos operandos são dois: os elementos na ordem em que estão presentes na lista, um elemento de cada vez e o resultado da iteração recursiva anterior ou nada, se ainda não for recursão.
Dessa maneira, você pode calcular o fatorial dos números ou concatenar cadeias.
fonte
Agregado usado para somar colunas em uma matriz inteira multidimensional
Selecionar com índice é usado na função Agregada para somar as colunas correspondentes e retornar uma nova matriz; {3 + 2 = 5, 1 + 4 = 5, 7 + 16 = 23, 8 + 5 = 13}.
Mas contar o número de trues em uma matriz booleana é mais difícil, pois o tipo acumulado (int) difere do tipo de origem (bool); aqui é necessária uma semente para usar a segunda sobrecarga.
fonte