I know simple linq, but here the problem statement has multiple level of nesting. How to write Linq or Lambda expression for nested collections.
我知道简单的linq,但这里的问题陈述有多层次的嵌套。如何为嵌套集合编写Linq或Lambda表达式。
Input Object Definition:
输入对象定义:
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()
{
...
}
}
The nesting can go to multiple levels
嵌套可以达到多个级别
Linq Expected Output
Linq预期产出
here I need to write Linq or Lambda expression which
在这里我需要编写Linq或Lambda表达式
- Gets all the Services
- Get service with a given name
获取所有服务
获取具有给定名称的服务
2 个解决方案
#1
If we can assume that you start with a list of services, like this:
如果我们可以假设您从服务列表开始,如下所示:
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>() },
}
},
};
Which looks like this:
看起来像这样:
Then this query will flatten the list out:
然后,此查询将展开列表:
Func<IEnumerable<Service>, IEnumerable<Service>> traverse = null;
traverse = ss =>
from s in ss
from s2 in new [] { s }.Concat(traverse(s.ChildServices))
select s2;
Calling traverse(services)
returns this:
调用遍历(服务)返回:
You can then look-up a service by name using a normal LINQ query or you could make a dictionary like this:
然后,您可以使用普通的LINQ查询按名称查找服务,或者您可以创建如下字典:
var serviceByName = traverse(services).ToDictionary(x => x.Name);
var serviceG = serviceByName["G"];
#2
I don't think there is direct way to recursively query nested collection (Atleast I'm aware).
我不认为有直接的方式来递归查询嵌套集合(我知道Atleast)。
Below solution might work for your cases.
以下解决方案可能适合您的情况。
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;
}
}
}
}
}
Working fiddler Sample
工作小提琴样品
#1
If we can assume that you start with a list of services, like this:
如果我们可以假设您从服务列表开始,如下所示:
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>() },
}
},
};
Which looks like this:
看起来像这样:
Then this query will flatten the list out:
然后,此查询将展开列表:
Func<IEnumerable<Service>, IEnumerable<Service>> traverse = null;
traverse = ss =>
from s in ss
from s2 in new [] { s }.Concat(traverse(s.ChildServices))
select s2;
Calling traverse(services)
returns this:
调用遍历(服务)返回:
You can then look-up a service by name using a normal LINQ query or you could make a dictionary like this:
然后,您可以使用普通的LINQ查询按名称查找服务,或者您可以创建如下字典:
var serviceByName = traverse(services).ToDictionary(x => x.Name);
var serviceG = serviceByName["G"];
#2
I don't think there is direct way to recursively query nested collection (Atleast I'm aware).
我不认为有直接的方式来递归查询嵌套集合(我知道Atleast)。
Below solution might work for your cases.
以下解决方案可能适合您的情况。
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;
}
}
}
}
}
Working fiddler Sample
工作小提琴样品