使用LINQ以最新的可用值填充列表

时间:2015-02-09 18:30:28

标签: c# linq time-series

我有一个包含

的数据对象
  1. 某份报告的公告日期,
  2. 以及当天宣布的价值
  3. 即。该课程看起来像:

        class Report
        {
        DateTime announcementDate;
        double ValueAnnounced;
        }
    

    因此,请考虑具有以下值的报告列表:

        List<Report> reports = new List<Report>;
        Report newReport = new Report();
        newReport.announcementDate =Convert.ToDateTime("1/1/2011"); newReport.ValueAnnounced = 5;reports.Add(newReport);
        newReport.announcementDate = Convert.ToDateTime("2/1/2011"); newReport.ValueAnnounced = 10;reports.Add(newReport);
        newReport.announcementDate = Convert.ToDateTime("3/1/2011"); newReport.ValueAnnounced = 15;reports.Add(newReport);
    

    现在,我需要的是,我需要创建一个新列表&#34;它将具有从2011年1月1日到2011年3月31日的每个日历日期公布的最新值。&#34 ;

    即。 linq将返回一个列表,其中包含以下元素:

        dailyReport[0].calendarDate = 1/1/2011; dailyReport[0].latestValue = 5;
        dailyReport[1].calendarDate = 1/2/2011; dailyReport[2].latestValue = 5;
        dailyReport[2].calendarDate = 1/3/2011; dailyReport[3].latestValue = 5;
        ...
        ...
        ...
        dailyReport[30].calendarDate = 2/1/2011; dailyReport[30].latestValue = 10;
        dailyReport[31].calendarDate = 2/2/2011; dailyReport[31]latestValue = 10;
        dailyReport[32].calendarDate = 2/3/2011; dailyReport[32].latestValue = 10;
        dailyReport[33].calendarDate = 2/4/2011; dailyReport[33].latestValue = 10;
        ...
        ...
        ...
        dailyReport[60].calendarDate = 3/1/2011; dailyReport[60].latestValue = 15;
        dailyReport[61].calendarDate = 3/2/2011; dailyReport[61].latestValue = 15;
        dailyReport[62].calendarDate = 3/3/2011; dailyReport[62].latestValue = 15;
        ...
        ...
        ...
        dailyReport[90].calendarDate = 3/31/2011; dailyReport[62].latestValue = 15;        
    

    我已经可以在这个循环的帮助下生成dailyReport列表:

        List<Report> dailyReport = new List<Report>;
    
    
        foreach (DateTime calendarDay in EachDay(StartDate, EndDate))
        {
                var latestAvailableReport =
                    (
                    from theReport in reports
                    where theReport.announcementDate <= calendarDay
                    orderby theReport.announcementDate descending
                    select theReport
                    ).ToList();
    
                Report newDailyReport = new Report();
                newDailyReport.announcementDate = latestAvailableReport[0].announcementDate;
                newDailyReport.ValueAnnounced = latestAvailableReport[0].ValueAnnounced;
                dailyReport.Add(newDailyReport);
    
        }
    

    和支持方法EachDay看起来像这样:

        public IEnumerable<DateTime> EachDay(DateTime from, DateTime thru)
        {
            for(var day = from.Date; day.Date <= thru.Date; day =day.AddDays(1))
            yield return day;
        }
    

    我的问题是,我可以感觉到应该有更快(或者更优雅)的方式来生成dailyReport列表 - 这基本上是&#34;用最新值填充&#34;原始列表的版本。

    我认为优雅的方式显然是一个聪明的LINQ设计 - 鉴于我目前的知识和能力,我无法弄清楚。

    请你帮我写LINQ吗?

    提前感谢您的兴趣和时间,非常感谢。

    Aykut Saribiyik

1 个答案:

答案 0 :(得分:1)

你想要达到什么目的?你问的是如何为你的问题编写一个好的代码,但是它本身没有好的代码,它总是有用的东西:性能,内存使用,可读性和可维护性等。< / p>

您现在正在做的是尝试提高性能,但会降低内存使用率和可维护性。

如果我是你,我会先写这样的代码:

public static class ReportListExtensions
{
    public static Report GetReport(this IEnumerable<Report> reports, DateTime date)
    {
        return new Report
        {
            AnnouncementDate = date,
            ValueAnnounced = reports.OrderByDescending(r => r.AnnouncementDate)
                                    .First(r => r.AnnouncementDate < date)
                                    .ValueAnnounced
        };
    }
}

此解决方案非常简单,易读且易于维护。您甚至不必触摸当前代码即可使用此功能。稍后您可以使用分析器查看是否存在性能问题并轻松改进此代码(预防性排序,缓存等)。

这肯定不是你问题的答案,但它可能会帮助你意识到也许你正在努力解决一个不存在的问题。