17

假设我有以下数据:

时间状态
10:00 开
11:00 关
12:00 关
13:00 关
14:00 关
15:00 开
16:00 开

我怎么能把使用 Linq 的东西分组到类似的东西中

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

4

5 回答 5

12

创建一个GroupAdjacent扩展,例如此处列出的扩展。

然后它很简单:

var groups = myData.GroupAdjacent(data => data.OnOffStatus);
于 2013-02-07T10:16:37.263 回答
5

您也可以使用一个 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);

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

于 2013-02-07T13:55:01.153 回答
4

这是一个核心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));
于 2013-02-07T13:42:49.960 回答
3

可以这样做。

  1. 迭代集合。
  2. 使用TakeWhile<Predicate>条件是集合的第一个元素的文本 On 或 Off。
  3. 迭代从第一点开始的子集并重复上述步骤并连接字符串。

希望能帮助到你..

于 2013-02-07T10:27:49.167 回答
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"}
            };

然后使用以下查询,您可以提取状态和分组时间:

    var query = timeStatuses.GroupBy(t => t.ContiguousKey)
    .Select(g => new { Status = g.First().Status, Times = g });
于 2013-02-07T10:38:12.810 回答