Darren Young
Darren Young

Reputation: 11090

C# - Multiple LINQ query into One?

I have used two LINQ queries to manipulate a datatable and return the data that I want. Effectively, the table has the following columns:

Group    Animal     Numbers

There can be multiple Animals within a single group, and multiple numbers assigned to a single animal. Initially I want to calculate the range of the numbers for each specific animal, and then calculate an average range for each group. With the output being the group number and then the average range.

I have the following two LINQ queries, that do work, however my question is, can this be merged into a single query, or , as they are distinct operations, should they be kept seperate for readability and testability?

 //Calculate range/delta for each number per animal
        var query = from data in Data.AsEnumerable()
                    group data by new { animal = data.Field<string>("animal"), gp = data.Field<string>("group") }
                        into g
                        orderby g.Key.gp
                        select new
                        {
                            animal = g.Key.animal,
                            gp = g.Key.gp,
                            delta = g.Max(c => Convert.ToDouble(c.Field<string>("numbers")))
                                    - g.Min(c => Convert.ToDouble(c.Field<string>("numbers")))

                        };

       //calculate average range/delta per group
        var temp = from q in query
                   group q by q.gp
                       into g
                       select new
                       {
                           gp = g.Key,
                           average = g.Average(c => c.delta)

                       };

Thanks.

Upvotes: 1

Views: 1423

Answers (2)

dtb
dtb

Reputation: 217243

You could first group the data by group and then, in a nested query, by animal to calculate the average of the deltas:

var result = from data in Data.AsEnumerable()
             group data by data.Field<string>("group") into g
             select new
             {
                 gp = g.Key,
                 average = (
                     from item in g
                     group item by data.Field<string>("animal") into f
                     select f.Max(c => double.Parse(c.Field<string>("numbers")))
                          - f.Min(c => double.Parse(c.Field<string>("numbers")))
                 ).Average()
             };

Upvotes: 0

neontapir
neontapir

Reputation: 4736

Because you aren't forcing the first query to evaluate with a method like ToArray(), there's no advantage to combining these queries. I would leave them separate for readability.

Upvotes: 5

Related Questions