flammable11
flammable11

Reputation: 51

Grouping data and making aggregate calculations in C#

I have something like this within a List<object> where object contains Cat, Type and Items.

Cat  | Type | Items
--------------------
 A   |  P   |  3
 A   |  Q   |  4
 A   |  R   |  2
 A   |  P   |  1
 A   |  Q   |  5
 B   |  P   |  2
 B   |  Q   |  1
 B   |  R   |  3
 B   |  P   |  9

What I want to do is calculate the average items of the types so produce something like this:

Cat  | Type | Items
--------------------
 A   |  P   |  2
 A   |  Q   |  4.5
 A   |  R   |  2
 B   |  P   |  5.5
 B   |  Q   |  3
 B   |  R   |  5

As you can see the average items are calculated for the types Whats the best way to do this?

Upvotes: 5

Views: 1266

Answers (2)

Aaron Carlson
Aaron Carlson

Reputation: 5762

class  Stuff
{
    public string Cat { get; set; }
    public string Type { get; set; }
    public double Items { get; set; }
}

static void Main( string[] args )
{
    var list = new List<Stuff>();
    list.Add( new Stuff { Cat = "A", Type = "P", Items = 3 } );
    list.Add( new Stuff { Cat = "A", Type = "Q", Items = 4 } );
    list.Add( new Stuff { Cat = "A", Type = "R", Items = 2 } );
    list.Add( new Stuff { Cat = "A", Type = "P", Items = 1 } );
    list.Add( new Stuff { Cat = "A", Type = "Q", Items = 5 } );
    list.Add( new Stuff { Cat = "B", Type = "P", Items = 2 } );
    list.Add( new Stuff { Cat = "B", Type = "Q", Items = 1 } );
    list.Add( new Stuff { Cat = "B", Type = "R", Items = 3 } );
    list.Add( new Stuff { Cat = "B", Type = "P", Items = 9 } );

    var result = from stuff in list
                 group stuff by new { stuff.Cat, stuff.Type } into g
                 select new { Cat = g.Key.Cat,
                              Type = g.Key.Type,
                              AvgItems = g.Average( s => s.Items ) };

    foreach( var s in result )
    {
        Console.WriteLine( "{0}  |  {1}  |  {2}", s.Cat, s.Type, s.AvgItems );
    }
}

Upvotes: 2

Timwi
Timwi

Reputation: 66573

Assuming the input is provided in a variable called list of type IEnumerable<Blah> (containing, for example, a database query result, a List<Blah>, an array, etc.etc.), and that Blah is a class with fields or properties called Cat, Type and Items:

var result = list.GroupBy(entry => new { entry.Cat, entry.Type })
                 .Select(group => new { group.Key.Cat, group.Key.Type,
                                        Items = group.Average(e => e.Items) })

Upvotes: 7

Related Questions