You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用C#和LINQ实现递归子项列表分配?

问题描述

类定义

public class MyModel
{
    public Options MyOptions { get; set; }
}

public class Options
{
    public IEnumerable<Options> Children { get; set; }
    public string SecondaryOptions { get; set; }
}

尝试的递归实现(存在子项丢失问题)

public static MyModel MapDetails()
{
    MyOptions.Children.Foreach(x => 
    if(!string.IsNullorEmtpy(x.SecondaryOptions))
    {
        x.Children = GetChild(x.SecondaryOptions, x);
    });
}
 
public static IEnumerable<Options> GetChild(string path, Options child)
{
    var childlist = optionsList; //基于path获取该列表

    childlist.Children.Foreach(child => 
    if(!string.IsNullorEmtpy(child.SecondaryOptions))
    {
        //需递归调用每个子项
        child.Children = GetChild(child.SecondaryOptions, child);
    });
}

需求与期望结构

遍历每个Options项,若其SecondaryOptions不为空或空字符串,则根据该字符串获取对应的子项列表并赋值给该项的Children属性,最终得到如下层级结构:

MyOptions.Children-
 A
   aa
     aaa
     aab
   ab
   ac
 B
   ba
   bb
 C

解决方案

原代码的核心问题

  1. 语法错误:Foreach应为ForEach(C#中List<T>的方法),string.IsNullorEmtpy拼写错误,正确为string.IsNullOrEmpty;且IEnumerable<T>本身没有ForEach方法,直接调用会报错。
  2. 递归逻辑错误:GetChild方法声明返回IEnumerable<Options>但未返回值,且直接修改传入对象的属性时未正确处理子项的递归赋值,导致子项丢失。
  3. 空值未处理:未给无SecondaryOptions的项设置空Children,容易引发空引用异常。

正确的递归实现(结合LINQ)

// 模拟根据path获取子项的方法,需替换为真实业务逻辑
private static IEnumerable<Options> GetOptionsByPath(string path)
{
    // 示例逻辑:根据path返回对应的子项列表
    return path switch
    {
        "root" => new List<Options>
        {
            new Options { SecondaryOptions = "A" },
            new Options { SecondaryOptions = "B" },
            new Options() // 对应层级中的C,无SecondaryOptions
        },
        "A" => new List<Options>
        {
            new Options { SecondaryOptions = "aa" },
            new Options(), // ab
            new Options()  // ac
        },
        "aa" => new List<Options> { new Options(), new Options() }, // aaa、aab
        "B" => new List<Options> { new Options(), new Options() }, // ba、bb
        _ => Enumerable.Empty<Options>()
    };
}

public static MyModel MapDetails()
{
    var model = new MyModel();
    // 构建根层级
    model.MyOptions = new Options
    {
        Children = BuildHierarchy(GetOptionsByPath("root"))
    };
    return model;
}

// 递归构建层级的核心方法,使用LINQ处理每个项
private static IEnumerable<Options> BuildHierarchy(IEnumerable<Options> items)
{
    return items.Select(item => 
    {
        if (!string.IsNullOrEmpty(item.SecondaryOptions))
        {
            // 递归获取并构建当前项的子层级
            item.Children = BuildHierarchy(GetOptionsByPath(item.SecondaryOptions));
        }
        else
        {
            // 无SecondaryOptions时设置空枚举,避免null
            item.Children = Enumerable.Empty<Options>();
        }
        return item;
    });
}

关键说明

  • LINQ的Select遍历:通过Select逐个处理每个项,确保每个节点都被递归处理,不会遗漏子项。
  • 递归逻辑清晰:BuildHierarchy专注于层级构建,数据获取逻辑抽离到GetOptionsByPath,职责分离更易维护。
  • 空值安全:给无SecondaryOptions的项设置空Children,避免后续遍历出现空引用异常。

内容的提问来源于stack exchange,提问作者Visva Kiruthika Muthuraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:42:52