[英]How can I merge contiguous periods?
Is there a simple way to merge contiguous periods ( StartDate
to EndDate
) having the same Value
? 有没有简单的方法来合并具有相同Value
连续时间段( StartDate
到EndDate
)?
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: 因此,这些行将合并如下:
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
2014-04-01 05-31-2014 71
4和5至2014-04-01 05-31-2014 71
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.