Lambda:有效地查找,修改,然后对元素进行分组

时间:2014-04-25 16:53:10

标签: c# lambda

我们说我有一个List<PageHit>,其中PageHit具有以下属性:<PageHitDateTime RequestTime

最终我要做的是将每个RequestTime值四舍五入到最近的30分钟增量(使用How can I round up the time to the nearest X minutes?),将它们组合在一起,并获得该增量块的PageResponseTime的总体平均值(真实世界的用户故事:跟踪每30分钟一次的平均页面响应时间。)

就我而言,但是我的大脑不会立刻向我展示如何在没有一些粗略循环的情况下有效地获得每个增量的平均值。有没有办法在第1步中执行此操作?

int PageResponseTime

3 个答案:

答案 0 :(得分:5)

Haven没有测试过,但这就是我要做的事情:

var avg = pageHitList.GroupBy(x => x.RequestTime.RoundUp(TimeSpan.FromMinutes(30)));
                     .Select(hit => new { 
                                 hit.Key, 
                                 Average = hit.Average(x => x.PageResponseTime) 
                             });

答案 1 :(得分:0)

首先,我将一个方法添加到PageHit类(或作为扩展方法)来计算舍入响应时间

    public class PageHit
    {
        public DateTime RequestTime { get; set; }
        public int PageResponseTime { get; set; }

        public DateTime GetRequestTimeToNearest30Mins()
        {
            return RoundUp(RequestTime, TimeSpan.FromMinutes(30));
        }
    }

然后你可以做类似下面的事情

    public void GetAverageRequestTimeByPeriod()
    {
        // Firstly project out both the PageHit and the rounded request time
        var averages = _pageHits.Select(t => new { RoundedTime = t.GetRequestTimeToNearest30Mins(), PageHit = t})
                                // Then Group them all by the rounded time, forming the blocks you mention
                                .GroupBy(t => t.RoundedTime)
                                // Project out the block time and the average of each page hit response time in the block
                                .Select(g => new { RequestTimeBlock = g.Key, AverageResponseTime = g.Average(t => t.PageHit.PageResponseTime)})
                                .ToArray();
    }

显然你想要对结果平均值做些什么,但我会把那部分留给你

答案 2 :(得分:0)

这样的事情应该有用......

        var averageByBlock = (from hit in pageHitList
                             group hit by hit.RequestTime into g
                             let groupCount = g.Count()
                             select new Tuple<DateTime, double>(g.Key, ((groupCount > 0) ? (g.Aggregate(0.0, (sum, ph) => sum + ph.PageResponseTime) / groupCount) : 0.0)));

我不确定这是否是最优化的,但我在100K条目列表上运行此代码并且运行速度非常快。