【问题标题】:How to write Linq or Lambda expression for nested collections如何为嵌套集合编写 Linq 或 Lambda 表达式
【发布时间】:2015-05-05 12:01:06
【问题描述】:

我知道简单的 linq,但这里的问题陈述有多层嵌套。如何为嵌套集合编写 Linq 或 Lambda 表达式。

输入对象定义:

public class Service
{
    public string Name { get; set; }
    public List<Service> ChildServices{ get; set; }

    public List<Action> AvailableActions{ get; set; }
}

public class Action
{
    public string Name { get; set; }
    public List<string> Parameters{ get; set; }

    public void Execute()
    {
        ...
    }
}

嵌套可以多层次

Linq 预期输出

这里我需要编写 Linq 或 Lambda 表达式

  1. 获取所有服务
  2. 使用给定名称获取服务

【问题讨论】:

  • 你的输出不需要访问定义的集合 - 除非我在这里误解了一些东西 - from s in Service select sfrom s in Service where s.Name == specifiedValue select s

标签: c# linq lambda nested


【解决方案1】:

如果我们可以假设您从服务列表开始,如下所示:

var services = new List<Service>()
{
    new Service()
    {
        Name = "A",
        ChildServices = new List<Service>()
        {
            new Service() { Name = "C", ChildServices = new List<Service>() },
            new Service()
            {
                Name = "D",
                ChildServices = new List<Service>()
                {
                    new Service() { Name = "E", ChildServices = new List<Service>() },
                    new Service() { Name = "F", ChildServices = new List<Service>() },
                }
            },
        }
    },
    new Service()
    {
        Name = "B",
        ChildServices = new List<Service>()
        {
            new Service() { Name = "G", ChildServices = new List<Service>() },
            new Service() { Name = "H", ChildServices = new List<Service>() },
        }
    },
};

看起来像这样:

然后这个查询会将列表展平:

Func<IEnumerable<Service>, IEnumerable<Service>> traverse = null;
traverse = ss =>
    from s in ss
    from s2 in new [] { s }.Concat(traverse(s.ChildServices))
    select s2;

调用traverse(services) 会返回:

然后您可以使用普通的 LINQ 查询按名称查找服务,或者您可以制作这样的字典:

var serviceByName = traverse(services).ToDictionary(x => x.Name);

var serviceG = serviceByName["G"];

【讨论】:

    【解决方案2】:

    我认为没有直接的方法来递归查询嵌套集合(至少我知道)。

    以下解决方案可能适用于您的情况。

    public class Service
    {
        public string Name { get; set; }
        public List<Service> ChildServices{ get; set; }
    
        public List<Action> AvailableActions{ get; set; }
    }
    
    public class Action
    {
        public string Name { get; set; }
        public List<string> Parameters{ get; set; }
    
        public void Execute()
        {
    
        }
    }
    
    public static class Extensions
    {
        public static IEnumerable<Service> GetAllServices(this Service node)
        {
            yield return node;
            if(node.ChildServices != null)
            {
                foreach(var child in node.ChildServices)
                {
                    foreach(var childOrDescendant in child.GetAllServices())
                    {
                        yield return childOrDescendant;
                    }
                }
            }
        }
    }
    

    工作提琴手Sample

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多