2012-05-23 120 views
0

难以置信的看起来像是一个简单的问题。我有linq last last的平均值

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); 
} 

我现在得到看起来像这样

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

数据最后我有

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

我现在需要得到的最后N个月的平均值,其中N是输入用户的文本框。 请建议如何使用Linq从有序集合中获取最后N个的平均值。谢谢

回答

3

如果你知道项目的集合中的号码(或使用Count())你可以跳过第一Count - N项目:

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

+1。请注意,如果您不能重新迭代集合,而不是Count()可能不是非常高性能的选择......不确定如何通过单次迭代来完成此操作。 –

+1

@AlexeiLevenkov:正如我在解决方案中所展示的那样,可以使用队列。 – recursive

+0

thx @BrokenGlass – Gullu

3

我创建了一个使用Queue<T>那并不是一个扩展方法t需要在序列上调用.Count,或者重复多次。

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; 
} 

要使用它,如果你的列表被称为sequence,只需拨打sequence.TakeLast(n)得到最后n记录。

+0

非常好,+1 – Jakob

+0

像你的解决方案和计划用于其他情况。现在@BrokenGlass的解决方案更简单。 +1 thx – Gullu