如何用LINQ实现筛选:排除所有状态均属有效列表的ProcessId?
问题:用LINQ筛选符合特定条件的ProcessItem记录
我有以下代码:
var validReasons = new List<string>{"CLOSE", "OPEN", "DEL", "ARCCHIVE", "HOLD", "REP"}; var processList = new List<ProcessItem>{ new ProcessItem{ProcessId = 1, Status = "ARCCHIVE"}, new ProcessItem{ProcessId = 1, Status = "ARCCHIVE"}, new ProcessItem{ProcessId = 3, Status = "xx"}, new ProcessItem{ProcessId = 3, Status = "xx"}, new ProcessItem{ProcessId = 4, Status = "xx"}, new ProcessItem{ProcessId = 5, Status = "xx"}, new ProcessItem{ProcessId = 5, Status = "xx"}, new ProcessItem{ProcessId = 6, Status = "CLOSE"}, new ProcessItem{ProcessId = 6, Status = "CLOSE"}, new ProcessItem{ProcessId = 6, Status = "xx"}}; var data = processList.GroupBy(p => p.ProcessId).Where(g => g.All(item => !validReasons.Contains(item.Status))).SelectMany(g => g).ToList(); foreach (var item in data) { Console.WriteLine($"ProcessId: {item.ProcessId}, Status: {item.Status}"); }
当前输出为:
ProcessId: 3, Status: xx ProcessId: 3, Status: xx ProcessId: 4, Status: xx ProcessId: 5, Status: xx ProcessId: 5, Status: xx
但我需要显示ProcessId为6的记录(因其并非所有状态都在validReasons列表中),期望输出应为:
ProcessId: 3, Status: xx ProcessId: 3, Status: xx ProcessId: 4, Status: xx ProcessId: 5, Status: xx ProcessId: 5, Status: xx ProcessId: 6, Status: CLOSE ProcessId: 6, Status: CLOSE ProcessId: 6, Status: xx
请问能否用LINQ实现该需求?
可以实现,只需修改LINQ中的筛选条件:
原代码的Where条件g.All(item => !validReasons.Contains(item.Status))表示组内所有项的Status都不在validReasons中,这会排除ProcessId=6的组(因为该组存在Status为CLOSE的项,属于validReasons)。
我们需要的是组内存在至少一个项的Status不在validReasons中,或者等价于组内不是所有项的Status都在validReasons中,对应两种写法:
写法一:使用Any判断存在不符合的项
var data = processList.GroupBy(p => p.ProcessId) .Where(g => g.Any(item => !validReasons.Contains(item.Status))) .SelectMany(g => g) .ToList();
写法二:取反All判断(逻辑等价)
var data = processList.GroupBy(p => p.ProcessId) .Where(g => !g.All(item => validReasons.Contains(item.Status))) .SelectMany(g => g) .ToList();
修改后执行代码,就能得到你期望的输出:保留所有组内存在非valid状态项的完整组数据,包括ProcessId=6的所有记录。
内容的提问来源于stack exchange,提问作者causita
相关产品推荐
相关产品推荐

