[英]C# LINQ - Return a typed filtered list based on a child property that is inside another list
Given the Objects : 给定对象:
class Parent
{
private int id;
public int Id
{
get { return id; }
set { id = value; }
}
private List<Child> childrenList;
public List<Child> ChildrenList
{
get { return childrenList; }
set { childrenList = value; }
}
}
class Child
{
private int idSub;
public int IdSub
{
get { return idSub; }
set { idSub = value; }
}
private bool isST;
public bool IsST
{
get { return isST; }
set { isST = value; }
}
}
I have a List<Parent> parentList = new List<Parent>()
and inside Parent
object there is a list of Child
which is called ChildrenList. 我有一个
List<Parent> parentList = new List<Parent>()
并且在Parent
对象内有一个称为List<Parent> parentList = new List<Parent>()
的Child
列表。
Child
has a property IsST
. Child
拥有财产IsST
。
I want to return only the Child
which has the property IsST
equals true and if the Parent
doesn't satisfy the condition, doesn't need to be returned. 我只想返回具有
IsST
属性等于true的Child
,并且如果Parent
不满足该条件,则不需要返回。
And both lists returned, need to be typed with its respectively types. 并且返回的两个列表都需要分别输入其类型。
What I have so far: 到目前为止,我有:
List<Parent> parentList = new List<Parent>()
{
new Parent()
{
Id = 1,
ChildrenList = new List<Child>()
{
new Child()
{
IdSub = 1,
IsST = true
},
new Child()
{
IdSub = 2,
IsST = true
}
}
},
new Parent()
{
Id = 2,
ChildrenList = new List<Child>()
{
new Child()
{
IdSub = 3,
IsST = false
},
new Child()
{
IdSub = 4,
IsST = true
}
}
},
new Parent()
{
Id = 3,
ChildrenList = new List<Child>()
{
new Child()
{
IdSub = 5,
IsST = false
},
new Child()
{
IdSub = 6,
IsST = false
}
}
}
};
var parentFilteredList = parentList
.Select(c => c.ChildrenList
.Where(d => d.IsST)
.ToList())
.ToList();
But the list of parents in the parentFilteredList
it's not of type List<Parent>
. 但是
parentFilteredList
中的父母列表不是List<Parent>
类型。
I need it to be List<Parent>
because the Parent
object in the real case there are a lot of properties, as well as the Child
. 我需要它是
List<Parent>
因为在实际情况下, Parent
对象以及Child
都有很多属性。 Select new
it's not an option. Select new
选项是不可行的。
Any help? 有什么帮助吗?
var parentFilteredList = parentList
.Select(c => c.ChildrenList
.Where(d => d.IsST)
.ToList())
.ToList();
In the following statement you are selecting the childrenList. 在下面的语句中,您正在选择childrenList。
var parentFilteredList = parentList
.Where(c => c.ChildrenList.Any(d => d.IsST)).ToList();
If you are looking to return all the parents where at least one child's ST is true - 如果您希望返回所有至少有一个孩子的ST的父母,则-
var parentFilteredList = parentList
.Where(c => c.ChildrenList.Any(d => d.IsST))
.ToList();
Or if you want to also filter the children's list inside these parents - 或者,如果您也要过滤这些父母中的孩子名单,
var parentFilteredList = parentList
.Where(c => c.ChildrenList.Any(d => d.IsST))
.Select(c =>
{
c.ChildrenList = c.ChildrenList.Where(d => d.IsST).ToList();
return c;
}).ToList();
Note that this will effect your original parents - I'm not sure that's a desirable outcome. 请注意,这会影响您的原父母-我不确定这是否是理想的结果。
The basic idea is to use SelectMany , but there are a couple wrinkles depending on assumptions. 基本思想是使用SelectMany ,但根据假设会有一些折衷 。
Basic code: 基本代码:
var list = parents.SelectMany
(
p => p.ChildrenList.Where( c => c.IsST )
);
The above assumes there are 0 or 1 children per parent that match. 上面假设每个父母有0个或1个匹配的孩子。 If you want to handle the case where a parent has two or more matching children, you'll need one of the variants below.
如果您要处理父母有两个或多个匹配孩子的情况,则需要以下变体之一。
If you want to throw an exception if a parent has two or more children that match: 如果您的父母有两个或多个匹配的孩子,如果您想引发异常:
var list = parents.SelectMany
(
p => p.ChildrenList.Single( c => c.IsST )
);
If you want to exclude parents that have two children that match: 如果要排除两个孩子匹配的父母:
var list = parents.SelectMany
(
p => p.ChildrenList.SingleOrDefault( c => c.IsST )
?? Enumerable.Empty<Child>()
);
If you want to include the first child that matches: 如果要包括第一个匹配的子项:
var list = parents.SelectMany
(
p => p.ChildrenList
.Where( c => c.IsST )
.Take(1)
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.