填充缺少日期的列表LINQ

时间:2014-08-21 14:15:43

标签: c# linq

我有以下对象列表

列表<百分比> MyList包含值

            date    high    low      avg
2014-08-21 16:15:00  20     10       22.5
2014-08-21 16:12:00  21     11  02
2014-08-21 16:09:00  25     12  23
2014-08-21 16:08:00  23     16  22
2014-08-21 16:07:00  19     09  21
2014-08-21 16:04:00  35     20  21.5
2014-08-21 16:03:00  45     25  19.5
2014-08-21 16:00:00  64     20  33.5
2014-08-21 15:56:00  32     25  27.5

public class Percentages
{
    public DateTime Date { get; set; }     
    public decimal High { get; set; }        
    public decimal Low { get; set; }        
    public decimal Average { get; set; }          
}

可以看出,该列表有一些缺失的时间。我的目标是使用上一个日期的值添加缺少的分钟列表。类似的东西:

            date    high    low      avg
2014-08-21 16:15:00  20     10       22.5
2014-08-21 16:14:00  21     11       02
2014-08-21 16:13:00  21     11       02
2014-08-21 16:12:00  21     11       02
2014-08-21 16:11:00  25     12       23
2014-08-21 16:10:00  25     12       23
2014-08-21 16:09:00  25     12       23
2014-08-21 16:08:00  23     16       22
2014-08-21 16:07:00  19     09       21
2014-08-21 16:06:00  35     20       21.5
2014-08-21 16:05:00  35     20       21.5
2014-08-21 16:04:00  35     20       21.5
2014-08-21 16:03:00  45     25       19.5
2014-08-21 16:02:00  64     20       33.5
2014-08-21 16:01:00  64     20       33.5
2014-08-21 16:00:00  64     20       33.5
2014-08-21 15:59:00  32     25       27.5
2014-08-21 15:58:00  32     25       27.5
2014-08-21 15:57:00  32     25       27.5
2014-08-21 15:56:00  32     25       27.5

我做了类似的事情(见下文),但似乎有点棘手,可能LINQ会更容易:

Mylist < Percentages > = ....
List< Percentages > tempList = new List <Percentages > 
for (int j = tempList.Count - 1; j> 0; j--) 
{
    if ( (tempList[j-1].Date - tempList[j].Date).TotalMinutes >1)
    {
        candles.Add(Mylist[j]);
    }
}

3 个答案:

答案 0 :(得分:1)

这应该有效,我已经使用过LINQ,因为你已经要求了。通常,您的需求在很大程度上取决于连续元素,这通常表明您应该使用普通循环而不是LINQ。

// ensure that it's sorted by date
percentages.Sort((p1, p2) => p1.Date.CompareTo(p2.Date));
List<Percentages> newPercentages = new List<Percentages>();
foreach (Percentages percentage in percentages)
{
    Percentages lastPercentage = newPercentages.LastOrDefault();
    if (lastPercentage != null)
    {
        TimeSpan diff = percentage.Date - lastPercentage.Date;
        int missingMinutes = (int)diff.TotalMinutes - 1;
        if(missingMinutes > 0)
        {
          var missing = Enumerable.Range(1, missingMinutes)
            .Select(n => new Percentages
            {
                Date = lastPercentage.Date.AddMinutes(n),
                Average = lastPercentage.Average,
                High = lastPercentage.High,
                Low = lastPercentage.Low
            });
          newPercentages.AddRange(missing);
        }
    }
    newPercentages.Add(percentage);
} 

答案 1 :(得分:1)

这是一个作为扩展方法的实现,因此您可以将其与其他LINQ方法链接起来:

public static class Extensions
{
    public static IEnumerable<Percentage> SubstituteMissingMinutes(this IEnumerable<Percentage> source)
    {
        if(source == null) throw new ArgumentNullException("source");
        return SubstituteMissingMinutesImpl(source.OrderBy(p => p.Date)).Reverse();
    }

    private static IEnumerable<Percentage> SubstituteMissingMinutesImpl(IEnumerable<Percentage> source)
    {
        Percentage previous = null;
        foreach (var Percentage in source)
        {
            if(previous != null)
            {
                var counter = previous.Date;
                while((counter = counter.AddMinutes(1)) < Percentage.Date){
                    yield return new Percentage{ Date = counter, Low = previous.Low, High = previous.High, Avg = previous.Avg };
                }
            }
            previous = Percentage;
            yield return Percentage;
        }        
    }
}

答案 2 :(得分:0)

以下内容:

        var date = DateTime.Parse("21.08.2014");
        var nextdate = date.AddDays(1);
        var list = new List<DateTime>();
        for (var i = date; i < nextdate; i = i.AddMinutes(1))
        {
            list.Add(i);
        }
        list.RemoveRange(tempList.Select(o=>o.Date).ToList());

现在列表应包含缺失值。

相关问题