Home > other >  Sample or Group primitive type and keep extremes
Sample or Group primitive type and keep extremes

Time:10-09

I have the following List which can contain 100,000 elements.

This is not what I'm looking for

int divisor = list.Count / n;
return list.Where((val, index) => index % divisor == 0).ToList();

I'm trying group the list into only 100 elements where each element is an average of 100 elements in the original list. However I also need to also include the min and max in each range.

CodePudding user response:

I think you can achieve what you want in this way using Take():

var resultList = list.Where((val, index) => index % divisor == 0).Take(100).ToList();
var min = resultList.Min();
var max = resultList.Max();

for Min() and Max() of each, you can do a loop.

CodePudding user response:

I think this is at least close to what you're looking for:

public readonly struct Bucket
{
    public Bucket(double average, int minimum, int maximum)
    {
        Average = average;
        Minimum = minimum;
        Maximum = maximum;
    }
    
    public double Average { get; }
    public int Minimum { get; }
    public int Maximum { get; }
}

public static class BucketExtensions
{
    public static IEnumerable<Bucket> ToBuckets(this IEnumerable<int> source, int bucketSize)
    {
        if (source is null) throw new ArgumentNullException(nameof(source));
        if (bucketSize < 1) throw new ArgumentOutOfRangeException(nameof(bucketSize));
        return ToBucketsIterator(source, bucketSize);
    }
        
    private static IEnumerable<Bucket> ToBucketsIterator(IEnumerable<int> source, int bucketSize)
    {
        int minimum = 0, maximum = 0;
        double sum = 0;
        int count = 0;
        
        foreach (int item in source)
        {
            if (count == 0 || minimum > item) minimum = item;
            if (count == 0 || maximum < item) maximum = item;
            sum  = item;
            count  ;
            
            if (count == bucketSize)
            {
                yield return new Bucket(sum / count, minimum, maximum);
                
                minimum = 0;
                maximum = 0;
                sum = 0;
                count = 0;
            }
        }
        
        if (count != 0)
        {
            yield return new Bucket(sum / count, minimum, maximum);
        }
    }
}

To get the details for every group of 100 elements in your list:

List<Bucket> buckets = list.ToBuckets(100).ToList();
  • Related