如何获取List<>中指定字符串项的下一项?状态起止时间生成遇阻
问题:按状态分组生成工作项的起止时间记录
我有一组包含版本号(rev)、状态(SystemState)和修改时间(SystemChangedDate)的数据列表,需要按状态字符串分组,生成每个状态对应的开始时间(该状态首次出现的修改时间)和结束时间(状态切换为下一个状态的修改时间)的输出结果。尝试用LINQ实现但未得到预期输出,现有代码如下:
List<WorkItemStateTime> workItems = new List<WorkItemStateTime>(); int totalCount = 0; int currentId = 1; string currentState; totalCount = revisionData.Count; do { WorkItemStateTime workItemStateTime = new WorkItemStateTime(); var currRow = revisionData.Where(x => x.rev == currentId).FirstOrDefault(); currentState = currRow.fields.SystemState; workItemStateTime.State = currentState; workItemStateTime.StartTime = currRow.fields.SystemChangedDate; var nextRow = revisionData.SkipWhile(x => x.fields.SystemState != currentState).Skip(1).FirstOrDefault(); currentId = nextRow.rev; workItemStateTime.EndTime = nextRow.fields.SystemChangedDate; workItems.Add(workItemStateTime); } while ((currentId - 1) < totalCount);
问题分析
现有代码的核心逻辑错误:SkipWhile(x => x.fields.SystemState != currentState).Skip(1)会跳过所有不等于当前状态的项,再取第一个,这无法正确找到当前版本的下一个状态项——当存在连续相同状态的记录时,会直接跳到该状态的最后一条之后,导致起止时间匹配错误。
修正后的实现
先确保数据按版本号升序排列,再按连续相同状态分组,提取每组的起止时间:
// 先确保数据按rev升序排列,保证遍历顺序正确 var sortedRevisions = revisionData.OrderBy(x => x.rev).ToList(); List<WorkItemStateTime> workItems = new List<WorkItemStateTime>(); if (!sortedRevisions.Any()) return workItems; int currentIndex = 0; while (currentIndex < sortedRevisions.Count) { var currentRevision = sortedRevisions[currentIndex]; string currentState = currentRevision.fields.SystemState; // 提取所有连续相同状态的记录 var sameStateGroup = sortedRevisions.Skip(currentIndex) .TakeWhile(x => x.fields.SystemState == currentState) .ToList(); var workItem = new WorkItemStateTime { State = currentState, StartTime = sameStateGroup.First().fields.SystemChangedDate }; // 结束时间为下一个状态的开始时间,最后一组无后续则设为null(可根据需求调整) if (currentIndex + sameStateGroup.Count < sortedRevisions.Count) { workItem.EndTime = sortedRevisions[currentIndex + sameStateGroup.Count].fields.SystemChangedDate; } else { workItem.EndTime = null; } workItems.Add(workItem); currentIndex += sameStateGroup.Count; }
关键修正点
- 排序保证顺序:先对
revisionData按rev升序排序,确保记录按版本时间顺序处理 - 连续状态分组:用
TakeWhile提取连续相同状态的记录,准确划分每个状态的时间区间 - 正确匹配结束时间:结束时间取当前状态区间后第一个记录的修改时间,最后一个状态无后续时设为
null(或当前时间,按需调整)
内容的提问来源于stack exchange,提问作者Lifewithsun
相关产品推荐
相关产品推荐

