简体   繁体   English

如何合并连续的期间?

[英]How can I merge contiguous periods?

Is there a simple way to merge contiguous periods ( StartDate to EndDate ) having the same Value ? 有没有简单的方法来合并具有相同Value连续时间段( StartDateEndDate )?

Input: 输入:

ID  StartDate   EndDate     Value 
1   2014-01-01  2014-01-31  71
2   2014-02-01  2014-02-28  71
3   2014-03-01  2014-03-31  71
4   2014-04-01  2014-04-30  50,12
5   2014-05-01  2014-05-31  50,12
6   2014-06-01  2014-06-30  71
7   2014-08-01  2014-08-31  71     (a month is skipped here)
8   2014-09-01  2014-09-30  71

So those lines will be merged as follows: 因此,这些行将合并如下:

  • 1, 2 and 3 to 01-01-2014 03-31-2014 71 1、2和3至01-01-2014 03-31-2014 71 1月1日01-01-2014 03-31-2014 71 3月31日01-01-2014 03-31-2014 71
  • 4 and 5 to 2014-04-01 05-31-2014 71 4和5至2014-04-01 05-31-2014 71
  • 6 will remain the same 6将保持不变
  • 7 and 8 to 2014-08-01 2014-09-30 71 7和8至2014-08-01 2014-09-30 71

Output should be: 输出应为:

StartDate   EndDate     Value 
2014-01-01  2014-03-31  71
2014-04-01  2014-05-31  50,12
2014-06-01  2014-06-30  71
2014-08-01  2014-09-30  71

I have tried this: 我已经试过了:

public List<PeriodInterval> MergePeriods(List<PeriodInterval> samples)
{
    var merged = samples.OrderBy(s => s.StartDate)
        .ThenBy(s => s.StartDate)
        //select each item with its index
        .Select((s, i) => new
        {
            sample = s, 
            index = i
        })
        // group by date miuns index to group consecutive items
        .GroupBy(si => new
        {
            date = si.StartDate.AddDays(1), 
            content = si.Valeur
        })                    
        .Select(g => new PeriodInterval
        {
            StartDate = g.Min(s => s.StartDate),
            EndDate = g.Max(s => s.EndDate),
            Valeur = g.First().Valeur
        });

    return merged.ToList();
}

Create extension method which batches sequential itemd by some condition, which checks two sequential items in source sequence: 创建扩展方法,该方法批量处理按某种条件排序的顺序项,该方法检查源顺序中的两个顺序项:

public static IEnumerable<IEnumerable<T>> SequentialGroup<T>(
    this IEnumerable<T> source, Func<T, T, bool> predicate)
{
    using(var iterator = source.GetEnumerator())
    {
        if (!iterator.MoveNext())
            yield break;

        List<T> batch = new List<T> { iterator.Current };

        while (iterator.MoveNext())
        {
            if (!predicate(batch[batch.Count - 1], iterator.Current))
            {
                yield return batch;
                batch = new List<T>();
            }

            batch.Add(iterator.Current);
        }

        if (batch.Any())
            yield return batch;
    }
}

With this method you can create batches of items which have sequential date and same value: 使用此方法,您可以创建具有连续日期和相同值的项目批:

items.SequentialGroup((a, b) =>
                a.Value == b.Value && (b.StartDate - a.EndDate).Days <= 1)

Creating aggregated items from these groups is easy. 从这些组中创建汇总项很容易。 Assume your items look like: 假设您的商品看起来像:

public class Item
{
    public DateTime StartDate { get; set; }
    public DateTime EndDate { get; set; }
    public string Value { get; set; }
    public string Line { get; set; }
}

Query: 查询:

var query = items.SequentialGroup((a, b) =>
    a.Value == b.Value && (b.StartDate - a.EndDate).Days <= 1)
                 .Select((g,i) => new Item {
                     Value = g.First().Value,
                     StartDate = g.Min(f => f.StartDate),
                     EndDate = g.Max(f => f.EndDate),
                     Line = String.Format("mergedLine_{0}", i + 1)
                 });

For your sample input output will be: 对于您的样本输入输出将是:

[
  {
    StartDate: "2014-01-01T00:00:00",
    EndDate: "2014-03-31T00:00:00",
    Value: "71",
    Line: "mergedLine_1"
  },
  {
    StartDate: "2014-04-01T00:00:00",
    EndDate: "2014-05-31T00:00:00",
    Value: "50,12",
    Line: "mergedLine_2"
  },
  {
    StartDate: "2014-06-01T00:00:00",
    EndDate: "2014-06-30T00:00:00",
    Value: "71",
    Line: "mergedLine_3"
  },
  {
    StartDate: "2014-08-01T00:00:00",
    EndDate: "2014-09-30T00:00:00",
    Value: "71",
    Line: "mergedLine_4"
  }
]

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

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