假设我有以下数据:
时间状态
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]]
创建一个GroupAdjacent
扩展,例如这里列出的扩展。
然后它就简单到:
var groups = myData.GroupAdjacent(data => data.OnOffStatus);
您也可以使用一个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);
基本上,它为每个项目分配一个键,当当前项目不等于前一个项目时,该键会递增。当然,这假设您的数据在列表或数组中,否则您将不得不尝试不同的方法
这里有一个核心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));
它可以作为.完成
- 遍历集合
- 使用
TakeWhile<Predicate>
条件是集合On或Off的第一个元素的文本 - 从第一点开始在的子集上迭代,重复上面的步骤并连接字符串
希望能有所帮助。。
您可以解析列表并分配一个连续键,例如定义一个类:
public class TimeStatus
{
public int ContiguousKey { get; set; }
public string Time { get; set; }
public string Status { get; set; }
}
您可以通过循环、保持计数和检测状态何时从"开"变为"关"等方式为连续键分配值,这将为您提供如下列表:
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 });