C# 选择符合条件的第一个对象或内部对象
我有一个类,它包含同一类的内部列表, 例如:C# 选择符合条件的第一个对象或内部对象,c#,lambda,ienumerable,C#,Lambda,Ienumerable,我有一个类,它包含同一类的内部列表, 例如: class Foo { string SearchId; List<Foo> GroupedPackages } 其中“response.lst”是一个foo列表,包是foo 如果可能的话,我希望在一行lambda表达式中执行此操作这将选择第一个Foo,并在顶层或GroupedPackages中的任何Foo实例中使用指定的SearchId Package = response.lst .Concat(respons
class Foo
{
string SearchId;
List<Foo> GroupedPackages
}
其中“response.lst”是一个foo列表,包是foo
如果可能的话,我希望在一行lambda表达式中执行此操作这将选择第一个
Foo
,并在顶层或GroupedPackages
中的任何Foo
实例中使用指定的SearchId
Package = response.lst
.Concat(response.lst
.Where(x => x.GroupedPackages != null)
.SelectMany(x => x.GroupedPackages)
)
.FirstOrDefault(x => x.SearchId == SearchId);
我首先向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);
在搜索之前,您需要先将列表展平 下面是如何将列表展平:
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 result = flatten(foos).Where(f => f.SearchId == SearchId).FirstOrDefault();
第一个是深度优先还是广度优先?您可能正在查找
SelectMany()
您当前只搜索结构中的一个级别。你打算递归地寻找第一个吗?所以如果你需要一个不同的条件,你必须写另一个函数?这基本上和我做的一样,只是有一个额外的方法。这是一个更好的一点,但我正在寻找像蒂姆的东西answer@Tim:当然,您也可以编写一个函数并给出一个ExpressionT>而不是一个固定的参数,但我想表达的想法是将条件放在一个地方,而不是为父元素和子元素分别编写条件。感谢您的想法,这似乎有点太复杂了不,只有一个层次的深度啊,那么,是的,它比你需要的更复杂。我建议您使用错误的结构,因为您的Foo
类确实允许多个级别。您将如何构建它以允许一个级别?@zivweisman-如下所示:class Foo{string SearchId;}class foooroot:Foo{List GroupedPackages;}
-然后顶级列表的类型是foooroot
。
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();