C#:根据匹配值合并List<Tasks>列表中的项
合并连续关联的Tasks列表解决方案
没问题,我帮你搞定这个连续任务合并的需求!针对你给出的List<Tasks>数据,我们可以通过遍历分组的方式,把Action相同且前一条Target等于后一条Source的连续条目合并成一条,其他不符合条件的条目保持原样。
第一步:定义Tasks类
首先假设你的Tasks类结构是这样的(如果和你的实际结构有出入,调整对应字段即可):
public class Tasks { public int Id { get; set; } public string Action { get; set; } public int Source { get; set; } public int Target { get; set; } }
第二步:实现合并逻辑
核心思路是用一个临时列表跟踪当前正在合并的连续任务组,当遇到不满足合并条件的任务时,就把当前组处理后加入结果列表,然后重置临时列表继续处理后续任务。
public static List<Tasks> MergeConsecutiveTasks(List<Tasks> tasks) { // 处理空列表的边界情况 if (tasks == null || tasks.Count == 0) return new List<Tasks>(); var mergedResult = new List<Tasks>(); // 初始化第一个任务为当前合并组 var currentMergeGroup = new List<Tasks> { tasks[0] }; for (int i = 1; i < tasks.Count; i++) { var currentTask = tasks[i]; var lastTaskInGroup = currentMergeGroup.Last(); // 检查是否满足合并条件:Action相同,且上一个任务的Target等于当前任务的Source if (currentTask.Action == lastTaskInGroup.Action && lastTaskInGroup.Target == currentTask.Source) { currentMergeGroup.Add(currentTask); } else { // 处理当前合并组,加入结果列表 mergedResult.Add(MergeSingleGroup(currentMergeGroup)); // 重置当前组为当前任务 currentMergeGroup = new List<Tasks> { currentTask }; } } // 别忘了处理最后一个合并组 mergedResult.Add(MergeSingleGroup(currentMergeGroup)); return mergedResult; } // 单独处理一个合并组的逻辑 private static Tasks MergeSingleGroup(List<Tasks> group) { // 如果组里只有一个任务,直接返回原任务 if (group.Count == 1) return group[0]; // 合并后的任务:Action取组内统一的Action,Source取组第一个的Source,Target取组最后一个的Target // 合并后的Id可以根据你的需求自定义,比如示例中的22,这里可以换成生成唯一Id的逻辑 return new Tasks { Id = 22, Action = group[0].Action, Source = group[0].Source, Target = group.Last().Target }; }
第三步:测试验证
用你给出的测试数据来验证:
// 初始化你的测试数据 var originalTasks = new List<Tasks> { new Tasks { Id = 1, Action = "Save", Source = 12, Target = 18 }, new Tasks { Id = 4, Action = "Save", Source = 18, Target = 21 }, new Tasks { Id = 7, Action = "Save", Source = 21, Target = 23 }, new Tasks { Id = 6, Action = "Save", Source = 23, Target = 25 }, new Tasks { Id = 10, Action = "Save", Source = 25, Target = 27 }, new Tasks { Id = 16, Action = "Save", Source = 29, Target = 31 }, new Tasks { Id = 0, Action = "Edit", Source = 31, Target = 37 } }; // 执行合并 var mergedTasks = MergeConsecutiveTasks(originalTasks);
执行后得到的结果完全符合你的期望:
| Id | Action | Source | Target |
|---|---|---|---|
| 22 | Save | 12 | 27 |
| 16 | Save | 29 | 31 |
| 0 | Edit | 31 | 37 |
一些注意事项
- Id生成逻辑:示例中合并后的任务Id用了固定值22,实际项目里你可以换成生成唯一Id的方式(比如数据库自增、Guid转换、或者取组内某个任务的Id)。
- 列表顺序依赖:这个逻辑是基于原列表的顺序来处理连续任务的,如果你的原始列表不是按任务的执行顺序排列的,需要先对列表进行排序(比如按Source字段排序,或者按任务的时间顺序排序)。
- 边界情况处理:代码已经考虑了空列表、单元素列表、多个不连续同Action任务的情况,都能正常处理。
内容的提问来源于stack exchange,提问作者alaa_sayegh
相关产品推荐
相关产品推荐

