我想使用Linq和DataTable来获取以下内容
DataTable内容
periodstart periodend value
2013-01-01 2013-02-01 10
2013-02-02 2013-03-01 10
2013-03-02 2013-04-01 15
2013-04-02 2013-05-01 20
2013-05-02 2013-06-01 10
2013-06-02 2013-07-02 20
结果
2013-01-01 2013-03-01 10
2013-03-02 2013-04-01 15
2013-04-02 2013-05-01 20
2013-05-02 2013-06-01 10
2013-06-02 2013-07-02 20
基本上我想按值对句点进行分组,但如果在一段时间内有不同的分组,也允许重复相同的值。
我想使用分段的最小值和最大值来分组,但这会给我一些类似的东西
2013-01-01 2013-06-01 10
2013-03-02 2013-04-01 15
2013-04-02 2013-07-02 20
这是不正确的。
如何解决此问题?
答案 0 :(得分:0)
(添加单独的答案,因为我现在删除的答案是错误的。)
听起来你只需要遍历所有行,保持一组直到值部分改变,然后取第一个元素的开头和最后一个元素的结尾。所以你可以做一些这样的扩展方法:
public static IEnumerable<IEnumerable<T>> GroupByContiguous<T, TKey>
(this IEnumerable<T> source, Func<T, TKey> groupSelector)
{
List<T> currentGroup = new List<T>();
T groupKey = default(T);
// This could be passed in as a parameter
EqualityComparer<T> comparer = EqualityComparer<T>.Default;
using (var iterator = source.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
groupKey = groupSelector(iterator.Current);
currentGroup.Add(iterator.Current);
while (iterator.MoveNext())
{
var item = iterator.Current;
var key = groupSelector(item);
if (!comparer.Equals(groupKey, key))
{
yield return currentGroup.Select(x => x);
currentGroup = new List<T>();
groupKey = key;
}
currentGroup.Add(item);
}
}
// Trailing group
yield return currentGroup.Select(x => x);
}
然后将其用作:
var query = table.AsEnumerable()
.GroupByContiguous(row => row.Field<int>("value"))
.Select(g => new {
Value = g.Key,
EarliestStart = g.First().Field<DateTime>("periodstart"),
LatestEnd = g.Last().Field<DateTime>("periodend")
});