How does the Linq Aggregate() extension method work?

Asked

Viewed 3,277 times

12

I just saw some examples that used the method Aggregate() of namespace System.Linq, but I couldn’t find any good explanation for how to use it.

What does this method and how it should be used?

  • 2

    Is this what you want? http://stackoverflow.com/q/7105505/221800

  • Yes @bigown, I was with that open question, but I thought it would be a good question here.

  • @jbueno do you understand English? could you please translate for us?

1 answer

11


I already answered that here, but not specifically on Aggregate, then I’ll isolate the part of the answer that matters.

The explanation is within the concept of using the Entity Framework, but you can use it for anything that uses Linq.

Aggregate has no equivalent in any and all database system. It is important to explain the concept of it before.

Suppose a ratio of 1 to N, or then from N to N. In our example, suppose the User now has permissions per screen (I will invent a Model called UsuarioPermissao, which is an associative table between Usuario and Permissao), which is stated in Model Usuario as follows:

public virtual ICollection<UsuarioPermissao> UsuarioPermissoes { get; set; }

For example make sense, I’ll match the Aggregate with another operator, called SelectMany. SelectMany is analogous to Select, but serves for a set of objects.

Suppose you would like to return all permissions of all users, their permissions being in a single line, separated by a comma (or so by a semicolon, whatever). The method Aggregate do it like this:

var resultado = db.Usuario.SelectMany(p => p.UsuarioPermissoes).
                          .Aggregate("",     // String inicial, chamada de 'acumulador'
                                     // A construção abaixo considera 'str' como a String acumulada e 'usuarioPermissao' como o registro atual da iteração
                                     (str, usuarioPermissao) => str + ", " + usuarioPermissao.Permissao.Nome).ToList();

Now I will translate the examples from here, which do not involve databases.

Example 1: Adding up numbers

var numeros = new[]{1,2,3,4};
var soma = numeros.Aggregate( (a,b) => a + b);
Console.WriteLine(soma); // resultado: 10 (1+2+3+4)

In this case, Aggregate accumulating the results of each sum in a, whereas b is the next number in the sequence.

  • Iteration 1: a == 1. a + 2 (b == 2). a receives 3;
  • Iteration 2: a == 3. a + 3 (b == 3). a receives 6;
  • Iteration 3: a == 6. a + 4 (b == 4). a gets 10.

Example 2: Concatenating comma-separated strings

var strings = new []{"a","b","c", "d"};
var stringFinal = strings.Aggregate( (a,b) => a + ',' + b);
Console.WriteLine(stringFinal); // resultado: a,b,c,d
  • Iteration 1: a == "a". a + ",b" (b == "b"). a receives "a,b";
  • Iteration 2: a == "a,b". a + ",c" (b == "c"). a receives "a,b,c";
  • Iteration 3: a == "a,b,c". a + ",d" (b == "d"). a receives "a,b,c,d";

Example 3: Multiplying numbers using a seed

For complete understanding, there is a Overload of Aggregate accepting a seed parameter.

var numeros = new []{10,20,30,40};
var valorMultiplicado = numeros.Aggregate(5, (a,b) => a * b); // A semente é 5
Console.WriteLine(valorMultiplicado); //Resultado: 1200000 ((((5*10)*20)*30)*40)

Example 4: Defining a delegate

Suppose you are reimplementing example 2 and want to put a more robust logic. There is a form of Aggregate which can be used by declaring a delegate as follows:

var strings = new []{"a","b","c", "d"};
var stringFinal = strings.Aggregate(new StringBuilder(), (a,b) => {
    if (a.Length > 0)
        a.Append(",");
    a.Append(b);
    return a;
});
Console.WriteLine(stringFinal);

Browser other questions tagged

You are not signed in. Login or sign up in order to post.