C# 按连续块分组的linq

C# 按连续块分组的linq,c#,linq,C#,Linq,假设我有以下数据: 时间状态 11:00休息 12:00休息 13:00休息 14:00休息 下午16:00 我如何使用Linq将其分组为 [开,[10:00],[关,[11:00,12:00,13:00,14:00],[开,[15:00,16:00]] 创建一个groupnextendent扩展名,如所列的扩展名 然后就简单到: var groups = myData.GroupAdjacent(data => data.OnOffStatus); 这可以按要求来做 对集合进行迭代

假设我有以下数据:

时间状态

11:00休息
12:00休息
13:00休息
14:00休息

下午16:00

我如何使用Linq将其分组为

[开,[10:00],[关,[11:00,12:00,13:00,14:00],[开,[15:00,16:00]]


创建一个
groupnextendent
扩展名,如所列的扩展名

然后就简单到:

var groups = myData.GroupAdjacent(data => data.OnOffStatus);
这可以按要求来做

  • 对集合进行迭代
  • 使用
    TakeWhile
    条件是打开或关闭集合的第一个元素的文本
  • 迭代起始点1的子集,重复上述步骤并连接字符串

  • 希望对您有所帮助。

    您可以解析列表并分配一个连续键,例如定义一个类:

    public class TimeStatus
    {
        public int ContiguousKey { get; set; }
        public string Time { get; set; }
        public string Status { get; set; }
    }
    
    您可以通过循环、维护计数和检测状态何时从On变为Off等方式将值分配给连续键,这将为您提供如下列表:

    List<TimeStatus> timeStatuses = new List<TimeStatus> 
                {
                    new TimeStatus { ContiguousKey = 1, Status = "On", Time = "10:00"},
                    new TimeStatus { ContiguousKey = 1, Status = "On", Time = "11:00"},
                    new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "12:00"},
                    new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "13:00"},
                    new TimeStatus { ContiguousKey = 2, Status = "Off", Time = "14:00"},
                    new TimeStatus { ContiguousKey = 3, Status = "On", Time = "15:00"},
                    new TimeStatus { ContiguousKey = 3, Status = "On", Time = "16:00"}
                };
    
    下面是一个硬核LINQ解决方案,它使用
    Enumerable.Zip
    比较连续元素并生成连续键:

    var adj = 0;
    var t = data.Zip(data.Skip(1).Concat(new TimeStatus[] { null }),
            (x, y) => new { x, key = (x == null || y == null || x.Status == y.Status) ? adj : adj++ }
        ).GroupBy(i => i.key, (k, g) => g.Select(e => e.x));
    

    您还可以使用一个Linq查询来实现这一点,该查询使用一个变量来跟踪更改,如下所示

    int key = 0;
    var query = data.Select(
        (n,i) => i == 0 ? 
            new { Value = n, Key = key } : 
            new 
            { 
                Value = n, 
                Key = n.OnOffFlag == data[i - 1].OnOffFlag ? key : ++key 
            })
        .GroupBy(a => a.Key, a => a.Value);
    

    基本上,它为每个项分配一个键,当当前项不等于前一项时,该键将递增。当然,这假设您的数据位于列表或数组中,否则您必须尝试另一种方法

    我认为这可能是重复的:问题是,根据以下数据,我能确定实体在给定时间是否处于打开/关闭状态吗?感谢上帝,我知道这是什么,而没有实际尝试解析此数据包中有
    groupnexting
    扩展方法。链接已断开,使得此答案不完整。谢谢;修复了链接。
    int key = 0;
    var query = data.Select(
        (n,i) => i == 0 ? 
            new { Value = n, Key = key } : 
            new 
            { 
                Value = n, 
                Key = n.OnOffFlag == data[i - 1].OnOffFlag ? key : ++key 
            })
        .GroupBy(a => a.Key, a => a.Value);