LINQ accepts the average number of fields in a query

I have a query like

select q1, q2, q3, q4, average from results

I need to calculate the average value from q1 to q5 in the middle column for each row. I have the following

var query = from T in db.results
                        select new ResultsCustom
                        {
                            q1, q2, q3, q4
                            average = ((double)(T.q1 ?? 0.0)
                                + (double)(T.q2 ?? 0.0)
                                + (double)(T.q3 ?? 0.0)
                                + (double)(T.q4 ?? 0.0)
                                ) / 4};

The problem is that q1 through q4 can be zero to throw away the average value. If they are zero, I do not want to include them in the average calculation. I thought I could reduce the score if there is a zero value. Is there a better way to do this?

+4
source share
4 answers

This will not translate to SQL, but you can do:

var query = from T in db.results
            select new ResultsCustom
            {
                q1, q2, q3, q4
                average = (new double?[] { T.q1, T.q2, T.q3, T.q4 }).Average()
            };

as it Average()will ignore null values.

To get the results and run the average in Linq-to-Objects:

var query = (from T in db.results select new {q1, q2, q3, q4}).AsEnumerable()
            .Select(r => new ResultsCustom
                 {
                     r.q1, r.q2, r.q3, r.q4,
                     average = (new double?[] { r.q1, r.q2, r.q3, r.q4 }).Average()
                 }
             );
+4
source

. sum / count.

...
let sum = q1.GetValueOrDefault() + q2.GetValueOrDefault() + ...
let count = (q1 != null ? 1 : 0) + ...
let avg = sum / count
...

, , , count == 0.

+1
double GetAverage(T)
{
    List<double> list = new List<double>();
    if (T.q1 != null) list.Add(T.q1);
    if (T.q2 != null) list.Add(T.q2);
    if (T.q3 != null) list.Add(T.q3);
    if (T.q4 != null) list.Add(T.q4);
    return list.Average();
}
0

( ):

double GetAverage(List<double> doublesList)
{
    var list = doublesList.Where(x => x != null).ToList();
    return list.Average();
}

which returns the average from a list of doublesany length, while nullsignoring it, separating the process from data collection.

0
source

Source: https://habr.com/ru/post/1540418/


All Articles