Home > Enterprise >  Calculating max, min, avg, median for the collection in C#
Calculating max, min, avg, median for the collection in C#

Time:10-31

I have a ConcurentBag where Bin is an object of 4 members (int Max, in Min, int Avg, double median). I have hundreds and sometimes thousands of Bin objects in the list, and have to calculate Max, Min, Avg, and Medium for each member:

                binnedGeoData.Max = mSingleGpsBinList.Select(x => x.Max).Max();
                binnedGeoData.Min = mSingleGpsBinList.Select(x => x.Min).Min();
                binnedGeoData.Avg = (int)mSingleGpsBinList.Select(x => x.Avg).Average();
                // Must convert to double[]
                double[] medArray = mSingleGpsBinList.Select(x => (double)x.Median).ToArray();
                binnedGeoData.Median = (int)Math.Round(Statistics.Median(medArray), 0);

However, somehow the result of all calculations gives me 0. For example if Max of bin1 is 4 and bi2n is 8, and bin3 is 2, The Max of those would be 8, but the result is 0.

One more thing: the collection can also be changed to SerializedCollection...

Any ideas?

CodePudding user response:

To be clear, is "mSingleGpsBinList" the list that contains a "bin object of 4 members" and "binnedGeoData" is another object that will hold calculated values of the list of bins? To get this you are selecting the "Max" property of each Bin, then the Max() of these values. If so, then your code all looks right. I would start by verifying that these properties are set and the getter is indeed returning a non-zero value.

If my understanding is off, let me know and provide the type of mSingleGpsBinList and binnedGeoData

CodePudding user response:

You're enumerating the source once per operator.

You shoild consider using the Aggregate operator:

var source = Enumerable.Range(0, 100);
var x = source.Aggregate<int, (int? min, int? max, long? sum, int count), (int? min, int? max, long? sum, int? avg, int count)>(
    default,
    (acc, i) =>
    {
        if (!acc.min.HasValue || (i < acc.min.GetValueOrDefault()))
        {
            acc.min = i;
        }

        if (!acc.max.HasValue || (i > acc.max.GetValueOrDefault()))
        {
            acc.max = i;
        }

        acc.sum = acc.sum.GetValueOrDefault()   i;

        acc.count  ;

        return acc;
    },
    acc => (acc.min, acc.max, acc.sum, (int?)(acc.sum / acc.count), acc.count));
  • Related