简体   繁体   中英

linq average of last N

Stumped with what looks like simple problem. I have

var SummaryCollection = (from n in ...long criteria with group by clause) 
into g select new 
{     MonthYear = g.Key, 
      Amount = g.Sum(p=>p.Amount)}).OrderBy(p=>p.MonthYear);
}

I now get data that looks like this

Jan2009 $100
Feb2009 $134
... and so on

Finally I have

  decimal avgAmount = (from x in SummaryCollection select x.Amount).Average();

I now need to get the average of last N months where N is input in a textbox by the user. Please advise how to get avg of last N from an ordered collection using Linq. thank you

If you know the number of items in the collection (or use Count() ) you can just skip over the first Count - N items:

 decimal avgAmount = SummaryCollection.Skip(SummaryCollection.Count() - N)
                                      .Select(x => x.Amount)
                                      .Average();

I created an extension method that uses a Queue<T> that doesn't require calling .Count on the sequence, or iterating more than once.

public static IEnumerable<T> TakeLast<T>(this IEnumerable<T> @this, int n) {
    var queue = new Queue<T>(n + 1);

    foreach (var element in @this) {
        queue.Enqueue(element);

        if(queue.Count > n) queue.Dequeue();
    }

    return queue;
}

To use it, if your list is called sequence , just call sequence.TakeLast(n) to get the last n records.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM