使用LINQ基于集合中现有对象的属性将对象插入到集合中

时间:2011-01-03 08:28:35

标签: c# .net linq

我有一个对象集合,其中包含如下数据:

FromTime                    Duration

2010-12-28                  24.0000

2010-12-29                  24.0000

2010-12-30                  24.0000

2010-12-31                  22.0000

2011-01-02                  1.9167

2011-01-03                  24.0000

2011-01-04                  24.0000

2011-01-05                  24.0000

2011-01-06                  24.0000

2011-01-07                  22.0000

2011-01-09                  1.9167

2011-01-10                  24.0000

在“FromTime”栏中,有数据“空白”,即2011-01-01和2011-01-08“缺失”。所以我想做的是循环一系列日期(在本例中为2010-12-28至2011-01-10)并“填写”持续时间为0的“缺失”数据。

当我刚开始使用LINQ时,我觉得应该“相当”容易,但我不能完全正确。我正在读“LINQ in Action”这本书,但觉得我还有很长的路要走,才能解决这个问题。所以任何帮助将不胜感激。

大卫

2 个答案:

答案 0 :(得分:3)

我会定义类如下:

public class DurDate
{
    public DateTime date = DateTime.ToDay;
    public decimal dure = 0;
}

并将编写像bellow一样的函数:

private IEnumerable<DurDate> GetAllDates(IEnumerable<DurDate> lstDur)
    {

        var min = lstDur.Min(x => x.date).Date;
        var max = lstDur.Max(x => x.date).Date;
        var nonexistenceDates = Enumerable.Range(0, (int) max.Subtract(min).TotalDays)
            .Where(x =>!lstDur.Any(p => p.date.Date == min.Date.AddDays(x)))
            .Select(p => new DurDate {date = min.Date.AddDays(p), dure = 0});

        return lstDur.Concat(nonexistenceDates).OrderBy(x=>x.date);
    }

示例测试用例:

List<DurDate> lstDur = new List<DurDate> { new DurDate { date = DateTime.Today, dure = 10 }, new DurDate { date = DateTime.Today.AddDays(-5), dure = 12 } };

编辑:这很简单,首先我会找到最小和最大范围:

var min = lstDur.Min(x => x.date).Date;
var max = lstDur.Max(x => x.date).Date;

在给定范围内没有的天数是什么:

Where(x =>!lstDur.Any(p => p.date.Date == min.Date.AddDays(x)))

找到这些日子后,我会选择它们:

Select(p => new DurDate {date = min.Date.AddDays(p), dure = 0})

最后将初始值连接到此列表(并对它们进行排序):

lstDur.Concat(nonexistenceDates).OrderBy(x=>x.date);

答案 1 :(得分:1)

这样的事情。我没有测试它,但我相信,你会得到这个想法:

    var data = new[]
               {
                   new  { Date = DateTime.Now.AddDays(-5), Duration = 3.56 },
                   new  { Date = DateTime.Now.AddDays(-3), Duration = 3.436 },
                   new  { Date = DateTime.Now.AddDays(-1), Duration = 1.56 },
               };

    Func<DateTime, DateTime, IEnumerable<DateTime>> range = (DateTime from, DateTime to) =>
                {
                    List<DateTime> dates = new List<DateTime>();
                    from = from.Date;
                    to = to.Date;
                    while (from <= to)
                    {
                        dates.Add(from);
                        from = from.AddDays(1);
                    }
                    return dates;
                };

    var result = range(data.Min(e => e.Date.Date), data.Max(e => e.Date.Date))
        .Join(data, e => e.Date.Date, e => e.Date, (d, x) => new {
                                                                     Date = d,
                                                                     Duration = x == null
                                                                         ? 0.0
                                                                         : x.Duration
                                                                 });

最好用一些静态方法替换这个范围的lambda。