简体   繁体   English

根据集合中现有对象的属性,使用LINQ将对象插入到集合中

[英]Insert objects into a collection with LINQ based on a property of the existing objects in the collection

I've got a collection of object which contains data as follows: 我有一个包含数据的对象集合,如下所示:

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

In the "FromTime" column, there are data "gaps" ie 2011-01-01 and 2011-01-08 are "missing". 在“ FromTime”列中,有数据“缺口”,即2011-01-01和2011-01-08为“缺失”。 So what I'd like to do is to loop through a range of dates (in this instance 2010-12-28 to 2011-01-10) and "fill in" the "missing" data with a duration of 0. 因此,我想做的是遍历一系列日期(在这种情况下为2010-12-28至2011-01-10),并以0的持续时间“填写”“缺失”数据。

As I've just started with LINQ, I feel that it should be "fairly" easy but I can't quite get it right. 正如我刚开始使用LINQ一样,我觉得它应该“很简单”,但是我做得还不够。 I'm reading the book "LINQ in Action" but feel that I'm still quite a way off before I can resolve this particular issue. 我正在阅读《 LINQ in Action》一书,但觉得在解决这个特定问题之前还有很长的路要走。 So any help would be much appreciated. 因此,任何帮助将不胜感激。

David 大卫

I'll define class like bellow: 我将像下面这样定义类:

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

and will wrote function like 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);
    }

Sample test case: 示例测试用例:

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

Edit: It works simply, first I'll going to find min and max range: 编辑:它的工作原理很简单,首先我要找到最小和最大范围:

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

What are the days not in the given range: 不在指定范围内的日期是:

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

After finding this days, I'll going to select them: 找到这几天之后,我将选择它们:

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

At last concatenate the initial values to this list (and sort them): 最后,将初始值连接到此列表(并对其进行排序):

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

Something like that. 这样的事情。 I didn't tested it, but I believe, that you will got the idea: 我没有测试过,但是我相信,您会明白的:

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

Also it would be better to replace this range lambda with some static method. 同样,最好用一些静态方法代替此范围λ。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM