0

我想将 Linq 与 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

这是不正确的。

如何解决这个问题?

4

1 回答 1

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")
                 });                
于 2013-05-16T16:32:16.713 回答