我有一个包含同一类的内部列表的类, 例如:
class Foo
{
string SearchId;
List<Foo> GroupedPackages
}
我想返回符合条件的第一个“foo”实例,它可以在主实例中或在内部列表中。
这就是我到目前为止 - 它有点难看,但它有效:
Package = response.lst.Where(p => p.SearchId == SearchId ||
(p.GroupedPackages != null &&
p.GroupedPackages.Any(m => m.SearchId==SearchId)))
.FirstOrDefault();
if (Package != null)
{
if (Package.SearchId != SearchId)
{
Package = Package.GroupedPackages.FirstOrDefault(m => m.SearchId == SearchId);
}
}
其中“response.lst”是foo的列表,而Package是foo。
如果可能的话,我希望在单行lambda表达式
中进行答案 0 :(得分:2)
这会在顶层或Foo
中的任意SearchId
个实例中选择指定Foo
的第一个GroupedPackages
。
Package = response.lst
.Concat(response.lst
.Where(x => x.GroupedPackages != null)
.SelectMany(x => x.GroupedPackages)
)
.FirstOrDefault(x => x.SearchId == SearchId);
答案 1 :(得分:1)
在搜索之前,您需要首先展平列表。
以下是如何扁平化列表:
Func<IEnumerable<Foo>, IEnumerable<Foo>> flatten = null;
flatten = fs =>
from f0 in fs
from f1 in new [] { f0, }.Concat(flatten(f0.GroupedPackages))
select f1;
所以,如果我从这个结构开始:
var foos = new List<Foo>()
{
new Foo()
{
SearchId = "Y",
GroupedPackages = new List<Foo>()
{
new Foo() { SearchId = "X" },
new Foo() { SearchId = "Z" },
new Foo()
{
SearchId = "W",
GroupedPackages = new List<Foo>()
{
new Foo() { SearchId = "G" },
new Foo() { SearchId = "H" },
}
}
}
}
};
我可以像这样压扁它:
flatten(foos);
得到的可枚举是:
那么这样做很简单:
var result = flatten(foos).Where(f => f.SearchId == SearchId).FirstOrDefault();
答案 2 :(得分:0)
我首先向Foo添加一个检查条件的函数:
class Foo {
public bool FulfillsCondition(int searchId) {
return this.SearchId==searchId;
}
}
然后添加一个函数来找到自己或孩子
class Foo {
public Foo FindItemToFulfillCondition(int searchId) {
if (this.FulfillsCondition) return this;
return GroupedPackages.FirstOrDefault(p => p.FulfillsCondition);
}
}
然后你可以
response.lst.Where(p => p.FindItemToFulfillCondition != null);