将最近2周的数据拆分为当前和上周

时间:2013-12-19 18:34:46

标签: c# linq highcharts

trendData是一个EventLogs列表,使用当前UTC日期作为结束日期和当前UTC日期的开始日期-13(数据库存储日期为UTC)

DateTime dUtcEnd = DateTime.UtcNow.Date;
DateTime dUtcStart = dUtcEnd.AddDays(-13);

var trendData = (from e in db.EventLogs
                where e.EventDateTime >= dUtcStart && e.EventDateTime <= dUtcEnd
                      && e.EventType == 'some event'
                select e).ToList();

为了填充当前和前几周的数组值,是否可以按周增量TakeSkip

沿着这些方向的东西?不知何故,我想TakeSkip需要以EventDateTime为基础,以确定当前和前几周的时间。

var currentTrend = trendData.Take(7).Reverse();
var previousTrend = trendData.Skip(7).Take(7).Reverse();

为了进一步了解正在尝试完成的内容,下面是如何填充Highcharts数组的想法。

返回的结果将包含3个数组。

WeeklyTrend results = new WeeklyTrend();
results.Categories = new string[7];
results.ThisWeek = new int[7];
results.LastWeek = new int[7];

使用今天的类别填充类别,每次为当前周减少一天。

int dayCounter = 6;
for (int i = 0; i < 7; i++)
{
    results.Categories[i] = dUtcEnd.AddDays(-dayCounter).ToShortDateString();
    dayCounter--;
}

查看Categories数组,以便找到EventDateTime与数组中的日期匹配的数组值。

foreach (var cTrend in currentTrend)
{
    var dayOfWeek = Array.FindIndex(results.Categories, c => c.Contains(cTrend.EventDateTime.ToShortDateString()));

    results.ThisWeek[dayOfWeek]++;
}

查看Categories数组,以便找到EventDateTime与数组中的日期匹配的数组值,并添加天数以匹配当前周...

foreach (var pTrend in previousTrend)
{
    var dayOfWeek = Array.FindIndex(results.Categories, c => c.Contains(pTrend.EventDateTime.AddDays(6).ToShortDateString()));

    results.LastWeek[dayOfWeek]++;
}

最终目标是填充Highcharts趋势图,该图表显示当前周与前一周相比的数据。

enter image description here

2 个答案:

答案 0 :(得分:1)

我倾向于在你的linq中使用GroupBy。考虑到这一点,我做了一个快速谷歌,并提出了一些在这里的SO。引起我注意的是这一个:

C# Linq or Lambda expression Group by Week IEnumerable list with date field

基本上,用它来解释:

DateTime dUtcEnd = DateTime.UtcNow.Date;
DateTime dUtcStart = dUtcEnd.AddDays(-13);

var eventLogs = new List<EventLogs>();

var weekTrendGroups = eventLogs
    .Where(x => x.EventDateTime >= dUtcStart 
                && x.EventDateTime <= dUtcEnd
                && x.EventType == "some event")
    .Select(p => new
    {
        Event = p,
        Year = p.EventDateTime.Year,
        Week = CultureInfo.InvariantCulture.Calendar.GetWeekOfYear
                (p.EventDateTime, CalendarWeekRule.FirstFourDayWeek, DayOfWeek.Monday)
    })
    .GroupBy(x => new { x.Year, x.Week })
    .Select((g, i) => new
    {
        WeekGroup = g,
        WeekNum = i + 1,
        Year = g.Key.Year,
        CalendarWeek = g.Key.Week
    });

foreach (var eventLogGroup in weekTrendGroups)
{
    Console.WriteLine("Week " + eventLogGroup.WeekNum);
    foreach (var proj in eventLogGroup.WeekGroup)
        Console.WriteLine("{0} {1} {2}",
            proj.Event.EventType,
            proj.Event.EventDateTime.ToString("d"),
            proj.Event.Id);
}

[edit] - 修复了与您的数据属性相匹配的功能。

所以,在这种情况下,这里的数据在DayOfWeek.Monday的边界上整齐地被截断。您当然可以改为适合。然后,您就可以在其中的群组中使用WeekNum和派对。

这看起来像一个简洁的解决方案,因为您当然可以将自己的谓词应用于它,以便根据您的需要对其进行切片。

答案 1 :(得分:0)

“不知何故,我认为Take和Skip需要以EventDateTime为基础,以确定当前和前几周的时间。”

你只是在寻找这个吗?

var previousTrend = trendData.OrderBy(e => e.EventDateTime).Take(7).Reverse();
var currentTrend = trendData.OrderBy(e => e.EventDateTime).Skip(7).Take(7).Reverse();