如何递归使用LINQ WHERE子句?实现Group层级中目标GroupDecision查找
递归查找包含指定字符串的GroupDecision对象
嘿,我来帮你搞定这个递归查找的问题!结合你提到的类结构和LINQ的需求,咱们一步步来实现。
首先,先确认一下你的类结构大概是这样的对吧?我先把它用代码写出来,方便后续对照:
public abstract class Group { } public class GroupGroup : Group { public List<Group> SubGroups { get; set; } = new List<Group>(); } public class GroupDecision : Group { public List<string> Keywords { get; set; } = new List<string>(); }
接下来,咱们写一个递归方法,用LINQ来筛选出所有包含目标字符串的GroupDecision。核心思路是:
- 如果当前
Group是GroupDecision,检查它的Keywords列表里有没有目标字符串,有的话就保留它 - 如果当前
Group是GroupGroup,就递归遍历它的所有子Group,收集子Group里符合条件的结果
直接上代码,我会在注释里解释关键部分:
public static IEnumerable<GroupDecision> FindDecisionsWithKeyword(Group rootGroup, string targetKeyword) { // 先处理当前节点:如果是GroupDecision且包含目标关键词,就返回这个节点的集合 if (rootGroup is GroupDecision decision && decision.Keywords.Contains(targetKeyword)) { yield return decision; } // 如果是GroupGroup,递归遍历所有子Group,并用SelectMany把嵌套的结果扁平化 if (rootGroup is GroupGroup group) { foreach (var subDecision in group.SubGroups .SelectMany(subGroup => FindDecisionsWithKeyword(subGroup, targetKeyword))) { yield return subDecision; } } }
关键LINQ部分解释
SelectMany:这里用来把每个子Group递归返回的IEnumerable<GroupDecision>合并成一个单一的集合,避免返回嵌套的列表,让结果更整洁。Contains:直接用来检查GroupDecision的关键词列表里是否存在目标字符串,简单直观。
调用示例
假设你有一个嵌套的Group结构,调用方法就像这样:
// 构建测试数据 var root = new GroupGroup { SubGroups = new List<Group> { new GroupDecision { Keywords = new List<string> { "apple", "banana" } }, new GroupGroup { SubGroups = new List<Group> { new GroupDecision { Keywords = new List<string> { "orange" } }, new GroupDecision { Keywords = new List<string> { "apple", "grape" } } } } } }; // 查找包含"apple"的GroupDecision var appleDecisions = FindDecisionsWithKeyword(root, "apple").ToList(); // 结果会包含第一个GroupDecision和最后一个GroupDecision
额外优化点(可选)
如果你担心子Group列表可能为null,可以在遍历前加个空值检查,比如:
if (rootGroup is GroupGroup group && group.SubGroups != null) { // 递归遍历逻辑 }
或者用LINQ的Where先过滤掉null的子Group:
group.SubGroups .Where(sub => sub != null) .SelectMany(subGroup => FindDecisionsWithKeyword(subGroup, targetKeyword))
这样就能更稳妥地处理可能的空引用情况啦~
内容的提问来源于stack exchange,提问作者user9145305
相关产品推荐
相关产品推荐

